创建两个模型之一时保存它们之间的关系

时间:2019-01-20 17:42:46

标签: django django-forms

我有3个(简化的)模型,我们将它们称为LocationThingWhere

class Location(models.Model):
    name = models.CharField()
class Thing(models.Model):
    name = models.CharField()
class Where(models.Model):
    location = models.ForeignKey(to = Location)
    thing = models.ForeignKey(to = Thing)

然后,我使用通用的CreateView创建了一个Location。但是我很难创建一个视图来创建Thing。我想要的是这样的表格:

class ThingForm(forms.Form):
    name = forms.CharField()
    location = forms.ModelChoiceField(queryset = Location.objects.all())

此表单使用用于创建新的Thing的数据,但也使用创建新的Where的日期。但是,我不知道如何创建新的Where

我的视图如下:

class ThingCreateView(generic.CreateView):
    model = Thing
    form_class = ThingForm
    success_url = 'somewhere/'

我了解到,在验证表单数据之后,我必须重写视图的form_valid函数才能做一些事情:

def form_valid(self, form):
    where = Where(location = form.location, thing = ???)
    where.save()
    return super().form_valid(form)

问题是:什么东西放?据我了解的文档,新创建的Thing尚未保存,因此我无法在数据库的Where表中引用它。

在创建Thing时如何在LocationThing之间建立关系?还是这是错误的方法,我需要编写自己的视图而不是使用通用的CreateView?甚至不同的东西?

1 个答案:

答案 0 :(得分:0)

作记录:所描述的构造是不可能的。 documentation说:

  

如果模型具有AutoField(自动递增的主键),则将在您首次调用save()时计算该自动递增的值并将其另存为对象上的属性[..]在调用save()之前先告诉ID值是什么,因为该值是由数据库而不是Django计算的。

由于Where表将包含Location和Thing的主键,因此在向该表添加新行时,它们必须可用。因此解决方案是不使用通用的CreateView,而是编写自定义视图:

def create(request):
    if request.method == 'POST':
        form = CreateForm(request.POST)
        if form.is_valid():
            t = Thing(name = form.cleaned_data['name'])
            t.save()
            w = Where(
                thing = t,
                location = form.cleaned_data['location'])
            w.save()
            return HttpResponseRedirect('/thing/{0}'.format(thing.id))
    else:
        form = CreateForm()

    return render(request, 'create_form.html', {'form': form})