2015-06-11 6 views
4

У меня есть ситуация снова, когда я делаю form.save(), моя форма сохраняет только родительскую таблицу, она не сохраняет таблицу промежуточных данных, которая требуется для отношений Many-to-Many ,ManyToManyField не сохраняет в django

Мой 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.

EDIT У меня есть обходной путь для этой проблемы, но я не уверен, что это самое лучшее решение. Если я смогу получить лучшее решение, я буду благодарен.

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

проверить синтаксис кода в модели Dataset: 'platform = models.ManyToManyField (Platform), через = 'DatasetPlatform') #, through_fields = ('Платформа: платформа', 'dataset'))' – Pynchia

+0

Oh .. I Извините, оригинальная модельная линия: platform = models.ManyToManyField (Platform, through = 'DatasetPlatform') Это то, что я использую, я не уверен, почему это проблема! – manugupt1

+0

Как раз так вы знаете, утверждение 'print' в представлениях Django не подходит. – xyres

ответ

5

Django не может (ну, отказывается) автоматически сохранять отношения m2m с помощью пользовательской модели. Сохранение данных формы использует прямое назначение для ManyToManyField, которое не будет работать, как описано here.

Если удаление пользовательской модели - это вариант, я бы сделал это. Конечно, это должно быть managed = True, но это значительно упрощает использование поля. Вы не сохраняете никаких дополнительных данных в отношениях, поэтому это может быть вариант.

В противном случае вы уже нашли единственное обходное решение. Каждый раз, когда вы хотите манипулировать отношения m2m, вам придется вручную создавать, изменять и удалять экземпляры DatasetPlatform. Опять же, это объясняется более подробно в relevant documentation.

Смежные вопросы