ManyToManyField不保存在django中

时间:2015-06-11 14:13:26

标签: python django

我有一种情况,当我执行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))

1 个答案:

答案 0 :(得分:6)

Django无法(好吧,拒绝)通过自定义模型自动保存m2m关系。保存表单数据使用直接分配到ManyToManyField,这不会像解释here那样有效。

如果删除自定义直通模型是一个选项,我会这样做。当然,它必须是managed = True,但它极大地简化了该领域的使用。你没有在关系中保存任何额外的数据,所以它可能是一个选项。

否则,您已找到唯一的解决方法。每次要操作m2m关系时,都必须手动创建,更改和删除DatasetPlatform实例。同样,这在relevant documentation中进一步详细解释。