基于get_initial()的CBV CreateView限制ForeignKey

时间:2013-09-05 01:07:46

标签: django foreign-keys django-queryset django-class-based-views

我有两个应用familyperson。在Person课程中,我想将可用的motherfather选项限制为已经创建的同一family的对象。如果我可以使用family_pkget_initial()设置的person/views.py:PersonCreateview,并使用family_pk来限制mother和{{1}的ForeignKey选项看起来它可能是一种分组逻辑的好方法。这可能吗?

father

family/models.py

class Family(models.Model): lastname=models.CharField(max_length=100) def __str__(self): return self.lastname

family.views.py

from django.views import generic from django.core.urlresolvers import reverse from .models import Family class FamilyListView(generic.ListView): context_object_name='family_list' model=Family class FamilyDetailView(generic.DetailView): context_object_name='family' model=Family pk_url_kwarg='family_pk' class FamilyCreateView(generic.CreateView): model=Family def get_success_url(self,**kwargs): return reverse('family-detail',kwargs={'family_pk':self.object.pk})

person/models.py

class Person(models.Model): fields=('family','firstname','mother','father') family=models.ForeignKey(Family) firstname=models.CharField(max_length=100) mother=models.ForeignKey('self',blank=True,null=True) father=models.ForeignKey('self',blank=True,null=True) def __str__(self): return self.firstname

person/views.py

1 个答案:

答案 0 :(得分:12)

这可能有点旧,但我通过这个答案找到了解决方案:https://stackoverflow.com/a/291968/1971587

我最终使其工作的方式实际上是使用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']])