Django:如何为页面上的每个元素创建表单?

Django: How to create forms for each element on the page?

我有Post的型号:

class Post(models.Model):
    text = models.CharField(max_length=10000)
    title = models.CharField(max_length=200)

在一页上我得到了所有 Post 个对象。对于每个 Post 对象,我想获取表单以在此页面上编辑此 Post。

为此,我创建了带有隐藏字段 "post_id" 的 PostEditForm 来识别编辑 post

class PostEditForm(forms.Form):
   title = forms.CharField(max_length=200)
   text = forms.CharField(widget=forms.Textarea)
   post_id = forms.IntegerField(widget=forms.HiddenInput)

我不知道如何在页面上获取此表单,以便 post_id 已被写入隐藏字段。

Django 为这个特定目的提供了 ModelForms

class PostEditForm(forms.ModelForm):
    title = forms.CharField(max_length=200)
    text = forms.CharField(widget=forms.Textarea)

def some_view(request,some_pk):
    post = models.Post.objects.get(pk=some_pk)
    if request.POST:
        form = PostEditForm(request.POST,instance=post)
        if form.is_valid():
            # do more if you like
            form.save()
    else:
        form = PostEditForm(instance=post)

    #return response

您可以在模板中呈现隐藏的表单字段 ({% for field in form.hidden_fields %}{{ field }}{% endif %}),但使用这种方法您不需要这样做。

我不认为你的方法是最简单的。最好创建一个表单,主要用作验证器:

class PostEditForm(forms.ModelForm):
    class Meta:
         model = Post

然后您需要使用 AJAX 从您的字段传递数据,并使用创建的表单验证它:

var form = $('.form'); // Your forms selector
form.on('submit', function(e){
    var self = $(this),
        post_id = self.attr('data-post-id');

    $.ajax({
      url: "/some-backend-url/",
      method: 'POST',
      data: {
         post_id: post_id,
         text: $('input.text', self).val(),
         title: $('input.title', self).val(),
      },
      dataType: 'json'
    }).done(function(response) {
      // Some callback here.
    });
});

并使用您的后端更新您的 post:

def some_view(request):
    if request.POST and request.is_ajax():
        post = models.Post.objects.get(pk=request.POST.get('post_id')
        form = PostEditForm(request.POST, instance=post)
        if form.is_valid():
            obj = form.save()
            # return json response
    return HttpResponseBadRequest

你也可以用基于 class 的 UpdateView 做同样的事情。