我正在编写一个Django应用程序,需要使用AJAX请求更新模型,该请求只包含模型字段的子集作为键。所以,如果我有模型
class TheModel(models.Model):
a = models.CharField(max_length=16)
b = models.IntegerField()
c = models.TextField()
d = models.ManyToManyField(AnotherModel)
然后我可以得到像
这样的请求id=7&a=Hello
id=7&a=Test&b=123
id=13&b=14&c=Description&d=6&d=10
也就是说,我将始终获取ID字段,但是其他任何子集。
我在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:
...
但这似乎不适用于m2m字段,而且model_to_dict对我来说感觉非常难看。所以我也做了
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()
但我并不完全了解如何在这里处理m2m字段。
在Django中有这样的惯用方法吗?在此先感谢您的帮助。
答案 0 :(得分:1)
首先,GET
请求永远不应更新数据。他们应该只读取和显示数据。您需要使用的HTTP方法是POST
。 This answer值得一读。
现在已经不在了,实现目标的最佳方法是使用通用UpdateView
。这是一些示例代码:
# 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, ])
一个简单的示例模板,用于在yourapp/templates/themodel_form.html
显示表单:
<form action="." method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update" />
</form>
现在,如果您的TheModel
实例已保存为1
,则可以通过转到http://your-website.co.uk/update-TheModel/1/
查看加载了初始数据的更新表单,然后您可以更新它点击Update
或向此页面的网址发送POST请求(以及CSRF token),这可以通过jQuery或vanilla Javascript在后台轻松完成。