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

Python 如何预填充Django更新表单并将其写回数据库,python,django,django-forms,modelform,Python,Django,Django Forms,Modelform,我是Python&Django的新手,目前正在苦苦挣扎。 我用Django模型表单创建了一个更新/编辑表单,但它只是不预先填充表单字段,同时将其发布到数据库中 我认为问题在于form=AdvertForm(request.POST或None,request.FILES或None,instance=form) 如果不使用request.POST或None、request.FILES或None,它会预填充字段,但不会将数据更新到数据库 这是我的视图。py: def update_advert(req

我是Python&Django的新手,目前正在苦苦挣扎。 我用Django模型表单创建了一个更新/编辑表单,但它只是不预先填充表单字段,同时将其发布到数据库中

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

如果不使用
request.POST或None、request.FILES或None,它会预填充字段,但不会将数据更新到数据库

这是我的
视图。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)
当我试图打开更新表单时,它看起来是这样的:

根据,您可以在实例化表单时使用
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)
在您的
广告表单中
,输入以下代码:

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
方法只是执行您在视图中所做的操作,将
请求.user
链接到实例,但是我将该代码放在form类中,以保持您的
视图的简单性

此外,我还发现了一个令人困惑(但并非至关重要)的问题——您混淆了变量名。
调用
form=get\u object\u或_404(Advert,pk=id)
时,应返回变量名,如
Advert
或类似名称。不是
form
,因为我们返回的是模型对象而不是表单,这可能会让人困惑。类似地,
form.save(commit=False)
返回一个“实例”,而不是模型表单。这不会解决您的问题,但应该指出,以便进一步澄清返回的确切内容以及如何命名变量。

谢谢。这真的帮助我更好地理解了我的代码!但它仍然没有显示带有“request.POST或None,request.FILES或None”的预填充字段。。。当我像这样使用它时:“form=AdvertForm(instance=advert_obj)”会显示预先填充的字段,但不会将其写回数据库……您能解释一下“show”是什么意思吗?发出
POST
请求时运行的代码
form=AdvertForm(request.POST或None,request.FILES或None,instance=advert\u obj)
应更新当前的
advert\u obj
。它不会再次显示这些字段,因为您正在重定向到
forum:user\u account
else
子句(当您发出
GET
请求时)会将数据预填充到您提到的表单字段中。这工作正常。但这一部分根本不应该保存到数据库中,因为我们只是在检索数据。
POST
请求负责保存(在您的情况下,更新当前的
advert\u obj
)以下是答案: