我有一种情况,当我执行form.save()时,我的表单只保存父表,它不保存多对多关系所需的中间表。
我的models.py看起来像这样
class Platform(models.Model):
id = models.AutoField(primary_key=True)
description = models.TextField(blank=True)
annotation_file_archived_location = models.FileField(upload_to='msrb/platform')
anntation_file_hashsum = models.TextField()
annotation = models.TextField(unique=True)
def __unicode__(self):
return self.annotation
class Meta:
managed = True
db_table = 'platform'
class Dataset(models.Model):
dataset_id = models.TextField(primary_key=True)
title = models.TextField(blank=True, null=True)
taxonomy = models.ForeignKey('Organism', blank=True, null=True)
citation = models.TextField(blank=True, null=True)
summary = models.TextField(blank=True, null=True)
contributor = models.TextField(blank=True, null=True) # This field type is a guess.
submitted = models.DateField(blank=True, null=True)
last_updated = models.DateField(blank=True, null=True)
author = models.ForeignKey('Users', db_column='author', blank=True, null=True)
platforms = models.ManyToManyField(Platform,through='DatasetPlatform')#,through_fields=('Platform:platform','dataset'))
class Meta:
managed = True
db_table = 'dataset'
class DatasetPlatform(models.Model):
id = models.IntegerField(primary_key=True)
platform = models.ForeignKey(Platform, null=False)
dataset = models.ForeignKey(Dataset,null=False)
class Meta:
managed = False
db_table = 'dataset_platform'
Forms.py
class DatasetForm(forms.ModelForm):
dataset_id = forms.CharField(required=True,help_text="dataset_id")
title = forms.CharField(required=True,help_text="title")
taxonomy = forms.ModelChoiceField(queryset=Organism.objects.all(),empty_label=None,help_text='Taxonomy')
citation = forms.CharField(required=True,help_text="citation")
summary = forms.CharField(required=True,help_text="summary")
contributor = forms.CharField(help_text="contributor (separated by comma)")
submitted = forms.DateField(initial = datetime.now,required=True,help_text="Submitted date")
last_updated = forms.DateField(initial = datetime.now,required=True,help_text="Last Updated date")
platform = forms.ModelMultipleChoiceField(queryset=Platform.objects.all(),help_text="Choose the platforms this dataset belongs to")
class Meta:
model = Dataset
fields = ('dataset_id','title','taxonomy','citation','summary','contributor','submitted','last_updated','platform')# Add author later ,'author')
views.py
def add_dataset(request):
context_dict = {}
if request.method == 'POST':
form = DatasetForm(request.POST)
if form.is_valid():
print "------------------------------------------------------------------------------"
print form.cleaned_data['platform']
form.save()
print "------------------------------------------------------------------------------"
return HttpResponseRedirect('/msrb/')
else:
print form
print form.errors
else:
form = DatasetForm()
context_dict['form'] = form
template = get_template('msrb/add_dataset.html')
context = RequestContext(request,context_dict)
return HttpResponse(template.render(context))
我尝试使用
保存数据form.save(commit=True)
form.save_m2m()
form.cleaned_data给出正确的输出。 我不知道我在这里错过了什么,因为我也没有收到来自django的错误消息。
修改 我有一个问题的解决方法,但我不确定这是否是最好的解决方案。如果我能得到更好的解决方案,我会很高兴。
def add_dataset(request):
context_dict = {}
if request.method == 'POST':
form = DatasetForm(request.POST)
if form.is_valid():
print form.cleaned_data['platform']
f = form.save()
for p in form.cleaned_data['platform']: <--- Added
d = DatasetPlatform(dataset = f,platform = p) <--- Added
d.save() <--- Added
return HttpResponseRedirect('/msrb/')
else:
print form
print form.errors
else:
form = DatasetForm()
context_dict['form'] = form
template = get_template('msrb/add_dataset.html')
context = RequestContext(request,context_dict)
return HttpResponse(template.render(context))
答案 0 :(得分:6)
Django无法(好吧,拒绝)通过自定义模型自动保存m2m关系。保存表单数据使用直接分配到ManyToManyField
,这不会像解释here那样有效。
如果删除自定义直通模型是一个选项,我会这样做。当然,它必须是managed = True
,但它极大地简化了该领域的使用。你没有在关系中保存任何额外的数据,所以它可能是一个选项。
否则,您已找到唯一的解决方法。每次要操作m2m关系时,都必须手动创建,更改和删除DatasetPlatform
实例。同样,这在relevant documentation中进一步详细解释。