Django CreateView验证字段不在字段中

时间:2013-10-13 10:40:29

标签: django django-forms django-generic-views

所以,我有一个Django通用视图:

class Foobaz(models.Model):
    name = models.CharField(max_length=140)
    organisation = models.ForeignKey(Organisation)


class FoobazForm(forms.ModelForm):
    class Meta:
        model = Foobaz
        fields = ('name')


class FoobazCreate(CreateView):
    form_class = FoobazForm

    @login_required
    def dispatch(self, *args, **kwargs):
        return super(FoobazCreate, self).dispatch(*args, **kwargs)

我要做的是从网址中获取组织ID:

/organisation/1/foobaz/create/

并将其添加回创建的对象。我意识到我可以在CreateView.form_valid()中执行此操作,但据我所知,这完全未经验证。

我已经尝试将其添加到get_form_kwargs(),但是这并不期望该组织会因为它不在所包含的字段中而显示出来。

理想情况下,我想要做的是将其添加到表单实例中以与其余部分进行验证 - 确保它是一个有效的组织,并且相关用户具有添加新foobaz的正确权限它。

如果这是最好的方式,我很高兴能够展示我自己的观点,但我可能只是错过了一个技巧。

谢谢!

2 个答案:

答案 0 :(得分:0)

我最好包含organisation字段并将其定义为隐藏和只读,这样django将为您验证它。

然后您可以覆盖get_queryset方法,如下所示:

def get_queryset(self):
    return Foobaz.objects.filter(
        organisation__id=self.kwargs['organisation_id'])

其中organisation_id是网址格式中的关键字。

答案 1 :(得分:0)

您可以覆盖视图的get_kwargs()方法和表格的save()方法。在get_kwargs() I"注入"将organization_id放入表单的初始数据中,并在save()中使用提供的初始数据检索缺少的信息:

在urls.py中:

urlpatterns('',
    #... Capture the organization_id
    url(r'^/organisation/(?P<organization_id>\d+)/foobaz/create/',
        FoobazCreate.as_view()),
    #...
)

在views.py中:

class FoobazCreate(CreateView):
    # Override get_kwargs() so you can pass
    # extra info to the form (via 'initial')
    # ...(all your other code remains the same)
    def get_form_kwargs(self):
        # get CreateView kwargs
        kw = super(CreateComment, self).get_form_kwargs()
        # Add any kwargs you need:
        kw['initial']['organiztion_id'] = self.kwargs['organization_id']
        # Or, altenatively, pass any View kwarg to the Form:
        # kw['initial'].update(self.kwargs)
        return kw

在forms.py中:

class FoobazForm(forms.ModelForm):
    # Override save() so that you can add any
    # missing field in the form to the model
    # ...(Idem)
    def save(self, commit=True):
        org_id = self.initial['organization_id']
        self.instance.organization = Organization.objects.get(pk=org_id)
        return super(FoobazForm, self).save(commit=commit)