保存具有外部关系和M2M关系的模型

时间:2019-08-21 10:01:39

标签: python django django-forms

我有3个模型,例如Fruits,Season和FruitSeason

class Fruit(models.Model):
    fruit_name = models.CharField(max_length=30)


class Season(models.Model):
    season_name = models.CharField(max_length=30)
    country = models.CharField(max_length=30)


class FruitSeason(models.Model):
    season = models.ForeignKey(Season, on_delete=models.CASCADE)
    fruit = models.ManyToManyField(Fruit)

我有一个表格,可以添加Season和(多个)水果详细信息

class FruitSeasonForm(forms.ModelForm):
    season_name = forms.CharField(max_length=30)
    fruit = forms.CharField(widget=forms.TextInput(
        attrs={'placeholder': 'Add comma separated values'}))
    class Meta:
        model = FruitSeason
        exclude('fruit', 'season')

我尝试将水果列表保存为“水果模型”中的个人记录,并将“季节详细信息”保存为“表格上的季节”。

views.py

class seasonal_fruit(request):
    if request.method == 'POST':
    form = FruitSeasonForm(request.POST)
    if form.is_valid():
        fruit_season_form = form.save(commit=False)

        season=Season.objects.create(season_name=form.cleaned_data['season_name'], country=form.cleaned_data['country'])

        fruit_season_form.save_m2m()
        form.save()

form post不能同时保存在两个模型上。 FruitSeason模型应具有水果ID和季节ID的记录。 我该如何解决?不知道我要去哪里错了。是这三个模型的建模还是其他?

1 个答案:

答案 0 :(得分:1)

您的变量命名令人困惑,并且您执行操作的顺序错误:

if form.is_valid():
    fruit_season = form.save(commit=False)
    season = Season.objects.create(...)
    fruit_season.season = season  # assign the fk
    fruit_season.save()  # now save the instance
    form.save_m2m()  # do this on the form, not on the instance and after all objects are saved

但这仅在fruit被定义为表单上的m2m字段时才有效,但由于您用逗号分隔的CharField替换了它,所以它不起作用。在您的情况下,您需要手动创建Fruit对象,然后将它们手动添加到fruit_season实例中。

if form.is_valid():
    fruits = []
    for fruit_str in form.cleaned_data['fruit'].split(","):
        fruit = Fruit.objects.create(name=fruit_str)
        fruits.append(fruit)
    fruit_season = form.save(commit=False)
    season = Season.objects.create(...)
    fruit_season.season = season
    fruit_season.save()
    fruit_season.fruit.set(fruits)