通过 Django 中的模型表单保存多对多数据
Posted
技术标签:
【中文标题】通过 Django 中的模型表单保存多对多数据【英文标题】:Saving Many To Many data via a modelform in Django 【发布时间】:2011-08-02 13:11:02 【问题描述】:我在保存表单中的多对多字段时遇到问题。这是我的模型:
class TextIssue(models.Model):
Issue = models.CharField(max_length=150, unique=True)
def __unicode__(self):
return self.Issue
class PadIssue(models.Model):
Issue = models.CharField(max_length=150, unique=True)
def __unicode__(self):
return self.Issue
class PHIssue(models.Model):
Data = models.ForeignKey(Data)
TextIssue = models.ManyToManyField(TextIssue, blank=True, null=True)
PadIssue = models.ManyToManyField(PadIssue, blank=True, null=True)
Notes = models.TextField()
def clean(self):
from django.core.exceptions import ValidationError
if self.TextIssue is None and self.PadIssue is None:
raise ValidationError('You must choose at least one issue category.')
if self.Notes is None:
raise ValidationError('You must write a note regarding the issues selected above.')
class PHIssueForm(ModelForm):
class Meta:
model = PHIssue
exclude = ('Data',)
这里我在views.py中处理post请求:
def process_npiform(request, npi_id=None):
if npi_id:
try:
npi = Data.objects.get(id=int(npi_id))
except:
raise Http404
if request.method == 'POST':
data = DataForm(request.POST, instance=npi, prefix='npi_data')
if data.is_valid():
update = data.save(commit=False)
if not request.user.is_superuser:
update.User = request.user
update.save()
if update.Status == 'past-due':
try:
prefab = PHIssue.objects.get(Data=npi)
except:
prefab = PHIssue(Data=Data.objects.get(id=int(update.id)))
prefab.save()
issue = PHIssueForm(request.POST, instance=prefab, prefix='npi_issue')
if issue.is_valid():
save_issue = issue.save(commit=False)
save_issue.save()
return HttpResponseRedirect(reverse('pm'))
else:
return render_to_response('npi/data.html', 'data': data, 'issue': issue, context_instance=RequestContext(request))
else:
return HttpResponseRedirect(reverse('pm'))
每当我通过表单保存时,只有 Notes 文本字段会保存在 PHIssue 实例中,并且多对多字段留空。有人可以帮我找出问题所在吗?
【问题讨论】:
【参考方案1】:你可以这样做 例如:
if todo_list_form.is_valid():
todo_list = todo_list_form.save(commit=False)
todo_list.save()
todo_list_form.save_m2m()
【讨论】:
+ for key takeaway — 在表单(不是实例)上调用save_m2m()
,因为:Django 将 save_m2m() 方法添加到您的 ModelForm 子类【参考方案2】:
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
使用commit=False
时,必须拨打save_m2m()
m2m 关系需要先保存父对象,而使用 commit=False
则不会这样做
【讨论】:
以上是关于通过 Django 中的模型表单保存多对多数据的主要内容,如果未能解决你的问题,请参考以下文章
Django - 使用表单集在不通过表的情况下建立 2 个模型之间的多对多关系