简体   繁体   English

使用ModelForm更新Django模型的某些字段

[英]Updating certain fields of Django model with ModelForm

I am writing a Django application and need to update a model with an AJAX request, which will only contain a subset of the model's fields as keys. 我正在编写Django应用程序,需要使用AJAX请求更新模型,该请求仅包含模型字段的子集作为键。 So if I have the model 所以如果我有模型

class TheModel(models.Model):
    a = models.CharField(max_length=16)
    b = models.IntegerField()
    c = models.TextField()
    d = models.ManyToManyField(AnotherModel)

then I could get requests like 然后我会收到类似的请求

id=7&a=Hello
id=7&a=Test&b=123
id=13&b=14&c=Description&d=6&d=10

that is, I will always get the ID field but any subset of the others. 也就是说,我将始终获取ID字段,但获取其他字段的任何子集。

I can't find a "nice" way to do this in Django 1.5: at first I tried 我在Django 1.5中找不到“不错”的方法:一开始我尝试过

instance = get_instance_or_404(request["id"])
data = django.forms.models.model_to_dict(instance)
data.update(request.POST)
form = TheModelForm(data, instance=instance)
if form.is_valid():
   form.save()
   ...
else:
   ...

but this doesn't seem to work well with the m2m field, and moreover model_to_dict feels incredibly ugly to me. 但这似乎不适用于m2m字段,而且model_to_dict对我来说很难受。 So I also did 所以我也做了

instance = get_instance_or_404(request["id"])
for k in TheModel._meta.fields:
    if k in request:
        setattr(instance, k, request[k])
try:
    instance.full_clean()
except ValidationError as e:
    ...
instance.save()

but I don't exactly understand how to handle the m2m fields here either. 但我也不完全了解如何处理此处的m2m字段。

Is there an idiomatic way to do this in Django? 在Django中有惯用的方法吗? Thanks in advance for your help. 在此先感谢您的帮助。

First of all, GET requests should never update data. 首先, GET请求永远不要更新数据。 They should only ever read and display data. 他们只能读取和显示数据。 The HTTP method you need to use is POST . 您需要使用的HTTP方法是POST This answer is worth a read. 这个答案值得一读。

Now that's out of the way, the best way to achieve what you want is by using the generic UpdateView . 既然这样,实现通用UpdateView的最佳方法就是使用通用的UpdateView Here's some sample code: 这是一些示例代码:

# urls.py
from views import UpdateTheModelView

urlpatterns = patterns('',
                       url(r'^update-TheModel/(?P<pk>\d+)/?',
                       UpdateTheModelView.as_view(),
                       name='update_the_model'),
)


# forms.py
from django import forms
from models import TheModel

class TheModelForm(forms.ModelForm):
    class Meta:
        model = TheModel
        fields = ('a', 'b', 'c', 'd',)


# views.py
from django.core.urlresolvers import reverse
from django.views.generic import UpdateView
from models import TheModel
from forms import TheModelForm

class UpdateTheModelView(UpdateView):
    model = TheModel
    form_class = TheModelForm
    template_name = 'themodel_form.html'

    def get_success_url(self):
        """
        Just here to redirect back to the update page when the form is posted
        """
        return reverse('update_the_model', args=[self.object.id, ])

And a simple example template to display the form at yourapp/templates/themodel_form.html : 还有一个简单的示例模板,用于在yourapp/templates/themodel_form.html显示表单:

<form action="." method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Update" />
</form>

So now if you have an instance of TheModel saved with an id of 1 , you can view the update form loaded with initial data by going to http://your-website.co.uk/update-TheModel/1/ and you can update it by clicking Update or by sending a POST request to this page's URL (along with the CSRF token ), which can easily be done in the background with jQuery or vanilla Javascript. 因此,现在,如果您保存了ID为1TheModel实例, TheModel可以访问http://your-website.co.uk/update-TheModel/1/查看加载了初始数据的更新表单,通过单击Update或通过向该页面的URL发送POST请求(以及CSRF令牌 )来更新它,可以使用jQuery或原始Javascript在后台轻松完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM