首页 > 解决方案 > 我可以在 django html 中添加表单吗?

问题描述

我想从具有自己的视图和模型的特定 html 中添加评论,并且我不想创建一个新的 html 文件,例如 comment.html,它只会显示表单及其视图。我希望用户能够在帖子下方发表评论,这样用户就不必单击“添加评论”之类的按钮,这会将他们带到带有“comment.form”的新页面,然后他们可以发表评论. 但我被困住了。我可以从管理页面手动添加评论,它工作正常,但似乎我必须创建另一个 url 和 html 文件来显示评论表单并让用户能够添加评论(顺便说一句,我正在尝试构建一个体育相关网站)。提前致谢!

我的模型.py:

class Transfernews(models.Model):
    player_name = models.CharField(max_length=255)
    player_image = models.CharField(max_length=2083)
    player_description = models.CharField(max_length=3000)
    date_posted = models.DateTimeField(default=timezone.now)

class Comment(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    transfernews = models.ForeignKey(Transfernews, related_name="comments", on_delete=models.CASCADE)
    body = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return '%s - %s' % (self.transfernews.player_name, self.user.username)

我的 forms.py :

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('body',)

我的意见.py:

def addcomment(request):
    model = Comment
    form_class = CommentForm
    template_name = 'transfernews.html'

我的 urls.py:

path('comment/', views.addcomment, name='comment'),

我的 transfernews.html:

<h2>Comments...</h2>

{% if not transfernew.comments.all %}
No comments Yet...
{% else %}
{% for comment in transfernew.comments.all %}
  <strong>
    {{ comment.user.username }} - {{ comment.date_added }}
  </strong>
  <br/>
  {{ comment.body }}
  <br/><br/>
  {% endfor %}
  {% endif %}
  <hr>
  <div>Comment and let us know your thoughts</div>
  <form method="POST">
    {% csrf_token %}
    <div class="bg-alert p-2">
    <div class="d-flex flex-row align-items-start"><textarea class="form-control ml-1 shadow-none textarea"></textarea></div>
    <div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit"> <a href="{% url 'comment' %}"></a>
    Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
    </div>
  </div>
  </form>

标签: djangodjango-modelsdjango-viewsdjango-formsdjango-templates

解决方案


我将您的问题解释为您想要一个包含所有转会新闻及其各自评论的页面以及旧评论下的评论表格。

这是一种常见的情况,使用通用视图可能会有所帮助,更具体地说是FormView。棘手的部分将是重组内容,以便您可以将您的 CommentForm 创建的评论与正确的 Transfernews 和用户链接。

所以我要做的是:

  1. 保留您拥有的模型。
  2. 编辑 CommentForm 类,使其也具有字段usertransfernews(见下文)。
  3. 创建一个继承自 的新视图django.views.generic.FormView。您将需要更改一些内置方法。主要是get_context_dataget_form_kwargs。第一个让您获得显示所有 transfernews 和早期评论所需的所有信息,后者让您为表格提供所有必要的信息。您还需要覆盖 form valid 以保存创建的实例。像这样的东西应该工作:
from django.forms import ModelForm
from django.views.generic import FormView
from transfer.models import Comment, Transfernews


class CommentForm(ModelForm):
    class Meta:
        model = Comment
        fields = ('body', 'user', 'transfernews')
        
    def __init__(self, *args, **kwargs):
        super(CommentForm, self).__init__(*args, **kwargs)


class TransfernewsView(FormView):
    template_name = 'transfernews.html'
    form_class = CommentForm
    success_url = '/transfers'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'transfernews': [
                {'news': transfer, 'comments': Comment.objects.all().filter(transfernews=transfer.id)}
                for transfer in Transfernews.objects.all()
            ]
        })
        return context

    def get_form_kwargs(self):
        form_kwargs = super().get_form_kwargs()
        if self.request.method in ('POST', 'PUT'):
            form_kwargs['data'] = form_kwargs['data'].copy()
            form_kwargs['data'].update({'user': self.request.user})
            
        return form_kwargs

    def form_valid(self, form):
        form.save()
        return super(TransfernewsView, self).form_valid(form)

  1. 更新您的urls.py,以便您像这样使用新视图:path('transfers/', views.TransfernewsView.as_view(), name='transfers'),

  2. 更新 HTML 文件,使每个 transfernews 都显示所有评论并有自己的表单。此表单必须同时包含body字段和隐藏字段,并带有transfernews.id. 下面是一个骨架。

<h1>Transfers</h1>

{% for transfer in transfernews %}
    Information on the transfer of player: {{ transfer.news.player_name }}
    ...
    {% for comment in transfer.comments %}
        <h5>Comment by {{ comment.user.username }}</h5>
        <div>{{ comment.body }}</div>
    {% endfor %}
    <from method='POST'>
         {% csrf_token %}
         <input id="transfernews" type="hidden" name="transfernews" value="{{ transfer.news.id }}">
         <input id="body" type="text" name="body">
         <input type="submit" value="Send comment"> 
    </form>
{% endfor %}

我希望这有帮助!

在编写 HTML 表单时,您还应该研究使用内置表单字段。即使用{{ form.body }}而不是使用<input id="body" type="text" name="body">。我看到你正在使用引导程序。自动引导样式的一种选择是crispy-forms。你应该调查一下;)


推荐阅读