如何在Django评论表单中自动填充Transfernews ID并隐藏该字段
解决评论自动关联Transfernews并隐藏字段的问题
我来帮你一步步搞定这个问题,核心思路就是让视图拿到当前要评论的Transfernews的ID,自动给评论的transfernews字段赋值,同时把这个字段从表单里隐藏,不让用户手动选择。
步骤1:调整URL路由(传递Transfernews的ID到视图)
首先得让每个Transfernews的详情页能把它的主键(pk)传给视图,这样视图才知道用户在评论哪条新闻。假设你原来的urls.py路由是:
path('transfer-targets/', views.transfer_targets, name='transfer-targets'),
把它改成:
path('transfer/<int:pk>/', views.transfer_targets, name='transfer-detail'),
这样用户访问/transfer/1/这类地址时,视图就能拿到对应Transfernews的ID(比如这里的1)。
步骤2:修改表单(移除/隐藏transfernews字段)
打开forms.py,直接把transfernews从字段列表里删掉就行,后端来控制赋值更安全:
class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ('body',) # 只保留评论内容字段,去掉transfernews
如果非要用隐藏字段的方式(不推荐,前端还是能篡改),可以这么写:
class CommentForm(forms.ModelForm): transfernews = forms.ModelChoiceField( queryset=Transfernews.objects.all(), widget=forms.HiddenInput() ) class Meta: model = Comment fields = ('body', 'transfernews')
但第一种方式更简洁,也更安全。
步骤3:更新视图(获取Transfernews并自动赋值)
修改views.py里的transfer_targets视图,让它接收pk参数,拿到对应的Transfernews对象,然后在保存评论时自动赋值:
from django.shortcuts import get_object_or_404, redirect from django.contrib.auth.decorators import login_required @login_required # 确保只有登录用户能评论 def transfer_targets(request, pk): # 获取当前要评论的Transfernews,不存在就返回404 transfernews = get_object_or_404(Transfernews, pk=pk) form = CommentForm(request.POST or None) if request.method == 'POST' and form.is_valid(): new_comment = form.save(commit=False) new_comment.user = request.user # 自动关联当前Transfernews new_comment.transfernews = transfernews new_comment.save() # 重定向回当前新闻页,避免重复提交 return redirect('transfer-detail', pk=pk) # 获取当前新闻的所有评论 comments = transfernews.comments.all() return render(request, 'transfernews.html', { 'transfer': transfernews, 'comments': comments, 'form': form })
这里加了@login_required装饰器,确保只有登录用户能评论,同时用get_object_or_404处理新闻不存在的情况,更健壮。
步骤4:修改模板(只显示评论内容输入框)
更新transfernews.html,移除transfernews字段的显示,同时确保页面展示当前新闻的内容:
<!-- 先展示当前Transfernews的内容 --> <h1>{{ transfer.player_name }}</h1> <img src="{{ transfer.player_image }}" alt="{{ transfer.player_name }}"> <p>{{ transfer.player_description }}</p> <p>发布时间: {{ transfer.date_posted }}</p> <!-- 评论列表区域 --> <h2>评论区...</h2> {% if not comments %} 还没有评论,快来抢沙发! {% else %} {% for comment in comments %} <strong>{{ comment.user.username }} - {{ comment.date_added }}</strong> <br/> {{ comment.body }} <br/><br/> {% endfor %} {% endif %} <hr> <!-- 评论表单 --> <div>写下你的看法吧</div> <form method="POST"> {% csrf_token %} {{ form|crispy }} <!-- 现在只会显示评论内容输入框 --> <button class="btn btn-primary btn-sm shadow-none" type="submit">发布评论</button> <button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">取消</button> </form>
这样用户在页面上只能看到评论输入框,提交后评论会自动关联到当前的Transfernews。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

