如何用Django实现类Twitter首页,解决登录后无法查看帖子问题
问题根因
- 问题1(登录后无法查看所有帖子):登录状态下视图返回的上下文没有传递提前查询好的
posts帖子列表变量,仅未登录时才返回了该变量,模板遍历帖子时找不到对应数据因此显示为空。 - 问题2(提交动态后表单消失):POST请求处理完提交逻辑后,返回给模板的
post是已保存的帖子模型对象,不是可渲染的表单实例,模板调用post.as_table时无法识别,因此表单区域无内容。
此外还有4个隐藏问题需要同步修复:
- 表单校验调用错误:
is_valid是方法不是属性,需写成is_valid()才会执行实际校验逻辑 - 帖子保存逻辑冗余:
NewPostForm.save(commit=False)已经返回NewPost模型实例,无需额外新建NewPost对象重复赋值 - POST请求后直接返回响应会导致用户刷新页面时重复提交表单,需用重定向跳转
- 模板循环变量名冲突:
{% for posts in posts %}中遍历变量和集合同名,会导致逻辑异常,需修改变量名
修复代码
1. views.py
from django.shortcuts import redirect def index(request): # 提前查询所有帖子,按时间倒序排列 posts = NewPost.objects.all().order_by("-timestamp") if request.user.is_authenticated: if request.method == "POST": form = NewPostForm(request.POST) if form.is_valid(): post = form.save(commit=False) post.user = request.user post.timestamp = datetime.now() post.save() # 提交成功后重定向到首页,避免刷新重复提交 return redirect("index") # GET请求、表单校验失败都返回空白表单 form = NewPostForm() # 登录状态同时返回表单和帖子列表 return render(request,"network/index.html",{ "form": form, "posts": posts }) # 未登录状态仅返回帖子列表 return render(request,"network/index.html",{ "posts": posts })
优化建议:给
NewPost模型的timestamp字段添加auto_now_add=True参数,创建对象时会自动填充当前时间,无需在视图中手动赋值。
2. 模板文件
{% extends "network/layout.html" %} {% block body %} <div style="margin: 10px 10px 10px 10px;"> <h1>All Posts</h1> {% if user.is_authenticated %} <div class="border border-success" style="margin: 10px 10px 10px 10px;"> <div style="margin: 10px 10px 10px 10px;"> <h3>New Post</h3> <form action="{% url 'index' %}" method="POST"> {% csrf_token %} <div class="form-group"> {{ form.as_table }} </div> <input class="btn btn-success" type="Submit" value="Post"> </form> </div> </div> {% endif %} <div id="posts" class="card"> <div class="card-body"> <!-- 修改变量名避免冲突 --> {% for post in posts %} <ul> <li class="card"> <div class="card-body"> <h5 class="card-title">{{ post.user }}</h5> <h6 class="card-subtitle text-muted">{{ post.timestamp }}</h6> <h3 class="card-text">{{ post.post }}</h3> </div> </li> </ul> {% empty %} <h6>No post availabel 😔</h6> {% endfor %} </div> </div> </div> {% endblock %}
内容的提问来源于stack exchange,提问作者lony235
相关产品推荐
相关产品推荐

