如何预填充Django Update表单并将其写回数据库

时间:2016-12-10 00:22:59

标签: python django django-forms modelform

我是编程Django和Python的新手,我现在正在努力奋斗:( !! 我使用Django Model表单创建了一个更新/编辑表单,但它没有预先填充表单字段并同时将其发布到数据库。

我认为问题在于:“form = AdvertForm(request.POST或None,request.FILES或None,instance = form)”

如果没有“request.POST或None,request.FILES或None”,它会预先填充字段,但不会更新数据库......

那是我的views.py:

def update_advert(request, id):
if not request.user.is_authenticated():
    return render(request, 'forum/login.html')
else:
    form = get_object_or_404(Advert, pk=id)
    if request.method == 'POST':
        form = AdvertForm(request.POST or None, request.FILES or None, instance=form)
        if form.is_valid():
            form = form.save(commit=False)
            form.user = request.user
            form.save()
            return redirect('forum:user_account')
    else:
        form = AdvertForm(instance=form) 


    context = {'form': form}
    return render(request, 'forum/update_advert.html', context)

当我看起来像这样,当我尝试打开更新表单时:

opening the form --> not prepopulated :(

1 个答案:

答案 0 :(得分:0)

根据https://docs.djangoproject.com/en/dev/ref/forms/api/#dynamic-initial-values,您可以在实例化表单时使用initial属性,以便预先填充表单。

def update_advert(request, id):
    if not request.user.is_authenticated():
        return render(request, 'forum/login.html')
    else:
        advert_obj = get_object_or_404(Advert, pk=id)


        if request.method == 'POST':
            form = AdvertForm(request.POST or None, request.FILES or None, instance=advert_obj)
            if form.is_valid():
                form.save()
                return redirect('forum:user_account')
        else:
            # Prepopulation happens here:
            data = {"some_field": advert_obj.some_val} # Insert all the values of advert_obj here and their field names as keys.
            form = AdvertForm(initial=data) 


        context = {'form': form}
        return render(request, 'forum/update_advert.html', context)

AdvertForm中,输入以下代码:

class AdvertForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(AdvertForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        instance = super(AdvertForm, self).save(commit=False)
        instance.user = self.request.user

        if commit:
            instance.save()
        return instance

重写save方法只是在视图中执行的操作将request.user链接到实例,但是我已将该代码放在表单类中以保留views简单。

另外,我可以看到一个令人困惑(但不是至关重要)的问题 - 你混淆了变量名称。 调用form = get_object_or_404(Advert, pk=id)时,应返回变量名称,例如advert或类似名称。不是form,因为我们返回的是模型对象而不是表单,因此可能会让人感到困惑。同样,form.save(commit=False)返回“实例”而不是模型形式。这不会解决您的问题,但应该指出更详细地说明返回的确切内容以及您应该如何命名变量。