Django 基于get_initial()的CBV CreateView限制外键

Django 基于get_initial()的CBV CreateView限制外键,django,foreign-keys,django-queryset,django-class-based-views,Django,Foreign Keys,Django Queryset,Django Class Based Views,我有两个应用程序,family和person。在Person类中,我想将可用的母亲和父亲选项限制为已创建的相同族的对象。如果我能利用家庭pk我在person/views.py:PersonCreateview中设置的家庭pk来限制母亲和父亲的外键选择,这似乎是一种很好的分组逻辑方法。这可能吗 family/models.py 类族(models.Model): lastname=models.CharField(最大长度=100) 定义(自我): 返回self.lastname family.

我有两个应用程序,
family
person
。在
Person
类中,我想将可用的
母亲
父亲
选项限制为已创建的相同
的对象。如果我能利用
家庭pk
我在
person/views.py:PersonCreateview
中设置的
家庭pk
来限制母亲和父亲的外键选择,这似乎是一种很好的分组逻辑方法。这可能吗

family/models.py

类族(models.Model):
lastname=models.CharField(最大长度=100)
定义(自我):
返回self.lastname
family.views.py

从django.views导入泛型
从django.core.urlResolver反向导入
从。模型导入族
类FamilyListView(generic.ListView):
上下文\u对象\u名称='family\u列表'
型号=系列
类FamilyDetailView(generic.DetailView):
上下文\u对象\u name='family'
型号=系列
pk_url_kwarg='family_pk'
类FamilyCreateView(generic.CreateView):
型号=系列
def get_success_url(自我,**kwargs):
返回反向('family-detail',kwargs={'family_pk':self.object.pk})
person/models.py

班级人员(models.Model):
字段=('family'、'firstname'、'mother'、'father')
族=模型。外键(族)
firstname=models.CharField(最大长度=100)
mother=models.ForeignKey('self',blank=True,null=True)
父=模型。外键('self',blank=True,null=True)
定义(自我):
返回self.firstname
person/views.py

从django.views导入泛型
从django.core.urlResolver反向导入
从django.shortcuts导入获取对象或404
从。模型进口人
从family.models导入族
类PersonDetailView(generic.DetailView):
模特=人
pk_url_kwarg='person_pk'
类PersonCreateView(generic.CreateView):
模特=人
def get_首字母(自身):
family=get\u object\u或\u 404(family,pk=self.kwargs.get('family\u pk'))
返回{'family':族,}
def get_success_url(自我,**kwargs):
返回反向('family:family detail',args=[self.kwargs['family_pk']))

这可能有点陈旧,但我通过以下答案找到了解决方案:

我最终使它工作的方法实际上是使用get_form()。因此,在你的情况下,我相信这样做会奏效:

class PersonCreateView(generic.CreateView):
    model = Person

    def get_family(self):
        return get_object_or_404(Family, pk=self.kwargs.get('family_pk'))

    def get_form(self, form_class):
        form = super(generic.CreateView, self).get_form(form_class)
        family = self.get_family()
        form.fields['mother'].queryset = Person.objects.filter(family)
        form.fields['father'].queryset = Person.objects.filter(family)
        return form

    def get_initial(self):
        initial = super(generic.CreateView, self).get_initial()
        initial['family'] = self.get_family()
        return initial

    def get_success_url(self, **kwargs):
        return reverse('family:family-detail', args=[self.kwargs['family_pk']])
我不认为get_initial()在这里仍然是必要的,但对于其他部分,它在您的情况下可能是必要的。