排除通用 CRUD 视图中的字段 [英] Excluding fields in generic CRUD views

查看:23
本文介绍了排除通用 CRUD 视图中的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 Domain 的模型,它看起来像这样:

class 域(models.Model):"""用于存储公司域的模型"""用户 = 模型.ForeignKey(用户)主机 = 模型.CharField(null=False,verbose_name="Host",max_length=128,unique=True)

我想使用 Django 的通用视图来对此进行 CRUD 操作.此模型中有一个字段需要用户输入,但外键字段不需要任何用户输入.如何从通用视图生成的表单中排除该字段,但为其分配当前经过身份验证的用户的值.

谢谢.

解决方案

django-users group 本周早些时候.

引用答案*:

<块引用>

表单和视图解决不同的问题.

View 正在解决我如何处理这个请求和将其转换为响应?".该表单正在解决如何我是否将此请求中的 POST 数据转换为模型对象(或更改为模型对象)?".

粗略地说,视图正在执行以下操作:

  1. 查看获取请求
  2. View 判断这是 GET 还是 POST
  3. 如果是 POST,View 会要求 Form 将 Post 转换为模型更改
  4. 表单返回成功或失败
  5. View 响应表单的成功或失败.
  6. 视图返回响应.

表单的功能是完整的子集视图的功能——出于这个原因,它是一个完全可互换的内部组件.

现在,在简单的情况下,视图可以猜测所有表单的默认值——它需要知道的是你正在处理与一个 Foo 模型,它可以构造一个默认的 Foo ModelForm.但是,如果您有更复杂的表单要求,需要一个定制的表单.

我们可以通过公开所有选项来实现这一点View 类上的 ModelForm;但为了保持一切干净,我们保持 ModelForm 隔离,并为 View 提供了一种方式指定要使用的 Form 类.

因此 - 为了涵盖排除字段的用例,您定义了一个排除字段的 ModelForm,然后让 CreateView 知道您要使用的表格:

class CampaignForm(forms.ModelForm):元类:模型 = 活动exclude = ('user', 'name', 'content_inlined')类 CreateCampaignView(CreateView):form_class = 活动表格template_name = "forms/create.html"

<块引用>

我猜当你说修复一个字段的值"时,你的意思是设置保存新文件之前的 user、name 和 content_inlined 的值活动实例;为此,您需要将一些额外的代码注入表单的表单处理逻辑:

class CreateCampaignView(CreateView):form_class = 活动表格template_name = "forms/create.html"def form_valid(self, form):form.instance.user = ...(有意义的东西...例如,self.request.user)return super(CreateCampaignView, self).form_valid(form)

<块引用>

当表单有效时,这会覆盖默认行为,并设置额外的值.然后 form_valid() 的 super() 实现将保存实例.

为了记录,这也可以通过覆盖 save() 来完成ModelForm 上的方法——然而,如果你这样做,你会失去请求对象,如果您尝试设置对请求敏感的事物的实例值.

*原始答案集self.object.user 而不是form.instance.user.这给出了一个 AttributeError 所以我在上面改变了它.

I have a model named Domain which looks like this:

class Domain(models.Model):
    """
    Model for storing the company domains
    """
    user = models.ForeignKey(
        User
    )
    host = models.CharField(
        null=False, verbose_name="Host", max_length=128, unique=True
    )

I'd like to use Django's generic views for doing CRUD operations on this. There is one field in this model that needs user input but the foreign key field doesn't need any user input. How can I exclude that field from the form that my generic view generates but assign it the value of the current authenticated user.

Thanks.

解决方案

Have a look at Russel's answer to a similar question on the django-users group earlier this week.

Quoting the answer*:

Forms and Views solve different problems.

The View is solving the problem of "how do I handle this request and convert it into a response?". The Form is solving the problem of "How do I convert the POST data in this request into a model object (or a change to a model object)?".

Very roughly, a view is doing the following:

  1. View gets a request
  2. View works out whether this is a GET or a POST
  3. If its a POST, View asks the Form to turn the Post into a model change
  4. Form returns success or failure
  5. View responds to the success or failure of the Form.
  6. View returns a response.

The functionality of the Form is a complete subset of the functionality of the View -- and for this reason, it's a completely interchangable internal component.

Now, in simple situations, it's possible for a View to guess all the defaults for the form -- all it needs to know is that you're dealing with a Foo model, and it can construct a default Foo ModelForm. However, if you have more sophisticated form requirements, you're going to need a customized Form.

We could have implemented this by exposing all the options of ModelForm on the View class; but in order to keep everything clean, we kept the ModelForm isolated, and provided the View with a way to specify which Form class it's going to use.

So - to cover your use case of excluding fields, you define a ModelForm that excludes the fields, then let the CreateView know the form you want to use:

class CampaignForm(forms.ModelForm):


    class Meta:
        model = Campaign
        exclude = ('user', 'name', 'content_inlined')

class CreateCampaignView(CreateView):
    form_class = CampaignForm
    template_name = "forms/create.html"

I'm guessing when you say "fix a values for a field", you mean setting the values of user, name and content_inlined before you save the new Campaign instance; to do this, you need to inject some extra code into the form processing logic of the form:

class CreateCampaignView(CreateView):
    form_class = CampaignForm
    template_name = "forms/create.html"

    def form_valid(self, form):
        form.instance.user = ... (something meaningful.. e.g., self.request.user)
        return super(CreateCampaignView, self).form_valid(form)

This overrides the default behavior when the form is valid, and sets the extra values. The super() implementation of form_valid() will then save the instance.

For the record, this could also be done by overriding the save() method on the ModelForm -- however, if you do that, you lose the request object, which you will need if you're trying to set the instance values to something that is request-sensitive.

*the original answer set self.object.user instead of form.instance.user. This gives an AttributeError so I have changed it above.

这篇关于排除通用 CRUD 视图中的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆