【发布时间】:2011-10-28 07:54:43
【问题描述】:
文档似乎很坚定,确实是这样......
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
而我特意指的是这一段:
当您的模型与另一个模型具有多对多关系时,会看到使用 commit=False 的另一个副作用。如果您的模型具有多对多关系并且您在保存表单时指定 commit=False,则 Django 无法立即保存多对多关系的表单数据。这是因为在实例存在于数据库中之前,无法为实例保存多对多数据。
为了解决这个问题,每次您使用 commit=False 保存表单时,Django 都会向您的 ModelForm 子类添加一个 save_m2m() 方法。手动保存表单生成的实例后,可以调用 save_m2m() 保存多对多表单数据。
我对 django 很陌生,昨天偶然发现了这个信息。
但是,我有一个视图,我不调用 save_m2m() 方法,但它实际上保存了 m2m 数据。
这是我的看法:
class SubscriberCreateView(AuthCreateView):
model = Subscriber
template_name = "forms/app.html"
form_class = SubscriberForm
success_url = "/app/subscribers/"
def get_form_kwargs(self):
kwargs = super(SubscriberCreateView, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
try:
self.object.full_clean()
except ValidationError:
form._errors["email"] = ErrorList([u"This subscriber email is already in your account."])
return super(SubscriberCreateView, self).form_invalid(form)
return super(SubscriberCreateView, self).form_valid(form)
我的模特:
class Subscriber(models.Model):
STATUS_CHOICES = (
(1, ('Subscribed')),
(2, ('Unsubscribed')),
(3, ('Marked as Spam')),
(4, ('Bounced')),
(5, ('Blocked')),
(6, ('Disabled')),
)
user = models.ForeignKey(User)
status = models.IntegerField(('status'), choices=STATUS_CHOICES, default=1)
email = models.EmailField()
subscriber_list = models.ManyToManyField('SubscriberList')
first_name = models.CharField(max_length=70, blank=True)
last_name = models.CharField(max_length=70, blank=True)
phone = models.CharField(max_length=20, blank=True)
facebook_id = models.CharField(max_length=40, blank=True)
twitter_id = models.CharField(max_length=40, blank=True)
address1 = models.CharField(max_length=100, blank=True)
address2 = models.CharField(max_length=100, blank=True)
postcode = models.CharField(max_length=10, blank=True)
city = models.CharField(max_length=30, blank=True)
country = models.CharField(max_length=30, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
class Meta:
unique_together = (
('user', 'email',),
)
def __unicode__(self):
return self.email
我的表格:
class SubscriberForm(ModelForm):
def __init__(self, user, *args, **kwargs):
super (SubscriberForm, self).__init__(*args, **kwargs)
self.fields['subscriber_list'].queryset = SubscriberList.objects.filter(user=user)
class Meta:
model = Subscriber
exclude = ('user', 'facebook_id', 'twitter_id')
那为什么我的观点有效呢? (意思是表单中某个字段的m2m关系实际上是在处理表单时保存的。)
【问题讨论】:
-
你能把你的模型和表格也贴出来吗?您的模型中的 m2m 在哪里?
-
我用模型和表格编辑了原始问题。 m2m 是另一个名为 SubscriberList 的模型。
标签: django django-models django-forms django-views