如何预填充Django Update表单并将其写回到数据库 [英] How to prepopulate an Django Update form and write it back to the database

查看:69
本文介绍了如何预填充Django Update表单并将其写回到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new at Python & Django and currently struggling right now. I created an update/edit form with Django Model forms, but it just doesn't prepopulate the form fields and post it to the database at the same time.

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

没有 request.POST或None,request.FILES或None ,它会确实填充字段,但不会将数据更新到数据库.

Without request.POST or None, request.FILES or None, it does prepopulate the fields but won't update the data to database.

这是我的 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)

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

In the moment it looks like this, when I try to open the update form:

打开表格->未预先填充:(

推荐答案

根据

According to https://docs.djangoproject.com/en/dev/ref/forms/api/#dynamic-initial-values, you can use the initial attribute when instantiating forms in order to prepropulate your forms.

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 中,输入以下代码:

In your AdvertForm, put this code:

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 简单.

The overriding save method simply does what you were doing in the views to link up the request.user to the instance, however I have placed that code in the form class to keep your views simple.

此外,我可以看到一个令人困惑(但不是至关重要)的问题-您混淆了变量名.调用 form = get_object_or_404(Advert,pk = id)时,它应该返回一个变量名,例如 advert 或类似名称.不是 form ,因为当我们返回模型对象而不是表单时,这可能会造成混淆.类似地, form.save(commit = False)返回一个实例"而不是模型表单.这不会解决您的问题,但应指出以进一步澄清确切返回的内容以及如何命名变量.

Also, I can see one confusing (but not vital) issue - you have mixed up the variable names. When calling form = get_object_or_404(Advert, pk=id), this should return to a variable name such as advert or something similar. Not form as that can be confusing as we are returning a model object not a form. Similarly, form.save(commit=False) returns an "instance" not a model form. This won't solve your problem but should be pointed out for more clarification on what exactly is being returned and how you should then name your variables.

这篇关于如何预填充Django Update表单并将其写回到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆