django modelform中的self.instance
在stackoverflow上看到一个问题,正好是我疑惑很久的相关问题。
[原问题地址]https://stackoverflow.com/questions/18265023/self-instance-in-django-modelform
What does self.instance in Django ModelForm constructor mean and where can I find a documentation about it?
class MyModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
if self.instance:
...
下面有大神回答:
In a ModelForm, self.instance is derived from the model attribute specified in the Meta class. Your self in this context is obviously an instance of your subclass of ModelForm, and self.instance is (and will be on saving the form without errors) an instance of the model class you specified, although you have not done so in your example.
Accessing self.instance in init may not work, though doing so after calling the parent's init probably will. Further, I wouldn't recommend trying to change the instance directly. If you are interested, have a look at the BaseModelForm code on Github. The instance can also be specified when creating a new form via the instance argument.
This is not a generic Python thing. This is something that's defined specifically by ModelForm, in the superclass init
大致意思是:在modelform中,self.instance来源于元类中指定的model属性。你的self明显是这个上下文中ModelForm子类的实例化,而self.instance是(将在没有错误的情况下保存在表单中)你指定的model类的一个实例。尽管你在示例中没有这么做。
直接在__init__中访问self.instance也许不会工作,虽然在调用父类的__init__后可能会生效。此外,我不建议直接更改实例。如果您感兴趣,请查看Github上的BaseModelForm代码。在通过实例参数创建新表单时也可以指定实例。
最后总结下:self.instance不是python中通用的方法,这是以ModelForm形式,在超类的__init__中特别定义的方法。
另一个回答:
You can find the documentation on django's website.
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-clean-method
Just search the page for every reference to "instance", and you should find what you need.
# Load up an instance
my_poll = Poll.objects.get(id=1)
# Declare a ModelForm with the instance
my_form = PollForm(request.POST, instance=my_poll)
# save() will return the model_form.instance attr which is the same as the model passed in
my_form.save() == my_poll == my_form.instance
他提到的是官方文档中关于instance例子,直接看官方的案例,我们可以找到我们问题的答案。
一共有三步,获取并加载一个对象实例,声明一个ModelForm的实例化,save()方法会返回model_form。实例属性与传入的model类型相同。
按照我的理解,这两个回答都指明了self.instance是modelform对象的实例化,包含了对象中的内容,我们可以通过self.instance访问并获取到对象的数据进行操作。关键在于,理清所实例化的对象在代码架构中的来龙去脉。
Fields are single data points, forms are a collection of fields.
思考题:想想为什么在django中form验证要设置clean()方法,它被设计出来的目的是什么?想要实现什么样的效果,在我们的代码结构中应该置于什么样的地位呢?
附录:
1.在django文档中,Model instance reference这部分提到Model.full_clean(exclude=None, validate_unique=True)。
There are three steps involved in validating a model:
- 验证模型字段 - Model.clean_fields()
- 验证模型作为一个整体 - Model.clean()
- 验证字段唯一性 - Model.validate_unique()
All three steps are performed when you call a model's ~Model.full_clean() method。而在我们使用ModelForm时,对 is_valid() 的调用将对表单上包含的所有字段执行这些验证步骤。
在文档的Form and field validation部分也重新讲解了clean()以及full_clean()方法,这是表单验证中最重要的部分!
2.在django文档中,提到了Model.pk属性。
粗略记录下:
For convenience, each model has an ~django.db.models.AutoField named id by default unless you explicitly specify primary_key=True on a field in your model. See the documentation for ~django.db.models.AutoField for more details.
为了方便起见,每个模型都默认有一个名为 id 的 AutoField,除非n你在模型中的字段上明确指定了 primary_key=True。
Regardless of whether you define a primary key field yourself, or let Django supply one for you, each model will have a property called pk. It behaves like a normal attribute on the model, but is actually an alias for whichever attribute is the primary key field for the model. You can read and set this value, just as you would for any other attribute, and it will update the correct field in the model.
无论是自定义主键字段还是django给你提供的,每个model都有一个名为PK 的属性。它是用于model主键字段的别名。你可以像对待其他字段属性一样,读取或设置值,它将更新模型中的正确字段。
3.文档中还提及,防止后台URL硬编码,我们最好在模板中使用 get_absolute_url()
You should avoid building the URL from unvalidated user input, in order to reduce possibilities of link or redirect poisoning::
def get_absolute_url(self):
return '/%s/' % self.name
If self.name is '/example.com' this returns '//example.com/' which, in turn, is a valid schema relative URL but not the expected '/%2Fexample.com/'.
下面是官方文档中列出的两个示例:
<!-- BAD template code. Avoid! -->
<a href="/people/{{ object.id }}/">{{ object.name }}</a> -------bad
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a> ---------good
这里的逻辑是,如果你更改对象的URL结构,即使是一些简单的,如更正拼写错误,您也不想跟踪每个可能创建的URL的地方。所以可以在 get_absolute_url() 中指定一次,并让所有其他代码调用一个地方。
4.在文档的Overriding the clean() method该部分中,提到:
You can override the clean() method on a model form to provide additional validation in the same way you can on a normal form.A model form instance attached to a model object will contain an instance attribute that gives its methods access to that specific model instance.
大意是,您可以在模型表单上覆盖 clean() 方法,用与正常表单上相同的方式实现自定义验证。附加到模型对象的模型表单实例将包含一个 instance 属性,该方法为其提供访问该特定model的实例。
django modelform中的self.instance的更多相关文章
- Django: ModelForm中Meta的fields等成员介绍
class MyForm(forms.ModelForm): realname = forms.CharField() phone = forms.CharField() class Meta: mo ...
- ModelForm 中选择框的数据 以及 instance 参数
ModelForm 中选择框的数据 print(list(self.fields['customer'].choices)) # [('', '---------'), (1, '张飞'), (2, ...
- django Modelform
前言: 为什么要用form去验证呢? 我们提交的是form表单,在看前端源码时如果检查到POST URL及我们提交的字段,如果没有验证我们是否可以直接POST数据到URL,后台并没有进行校验,直接处理 ...
- python 全栈开发,Day110(django ModelForm,客户管理之 编辑权限(一))
昨日内容回顾 1. 简述权限管理的实现原理. 粒度控制到按钮级别的权限控制 - 用户登陆成功之后,将权限和菜单信息放入session - 每次请求时,在中间件中做权限校验 - inclusion_ta ...
- Django - ModelForm组件
一.ModelForm组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样一张学生表, ...
- 【python】-- Django ModelForm
Django ModelForm Django的ModelForm的验证方式相比较form + Model的验证方式有下列区别: ModelForm没有form + Model的低耦合性 ModelF ...
- django Modelform 使用
前言: 为什么要用form去验证呢? 我们提交的是form表单,在看前端源码时如果检查到POST URL及我们提交的字段,如果没有验证我们是否可以直接POST数据到URL,后台并没有进行校验,直接处理 ...
- Django ModelForm操作及验证
一.内容回顾 Model - 数据库操作 - 验证 class A(MOdel): user = email = pwd = Form - class LoginForm(Form): email = ...
- Django ORM中常用字段和参数
一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...
随机推荐
- 什么是AWS Lambda?——事件驱动的函数执行环境
AWS CTO Werner Vogels在AWS re:Invent 2014大会的第二场主题演讲上公布了两个新服务和一系列新的实例,两个新服务都相当令人瞩目:第一个宣布的新服务是Amazon EC ...
- python+Django实现Nagios自动化添加监控项目
最近机房刚上了一批机器(有100台左右),需要使用Nagios对这一批机器进行监控.领导要求两天时间完成所有主机的监控.从原来的经验来看,两天时间肯定完成不了.那怎么办?按照之前的想法,肯定是在nag ...
- 如何更快更好的写出cnblog博客?windows live writer推荐
之前总是会羡慕网上那些技术牛人的博客都写的那么给力,后来一搜发现还是有工具可用的. 这里就推荐一款写博客的"神器",Windows Live Writer (Get It Now! ...
- Code:NFine目录
ylbtech-Code:NFine目录 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylb ...
- easy_install 和 pip
原文章:http://blog.csdn.net/xsj_blog/article/details/52037609 easy_install 和 pip的介绍: easy_install和pip都是 ...
- 3.清除dns缓存的意义及命令?
1.dos命令:ipconfig /flushdns 2.意义: 简单地说就是 www.baidu.com ,www.sina.com 这些就是DNS域名.但是计算机不能直接通过DNS域名访问服务器( ...
- 【原】RHEL6.0企业版安装
作者:david_zhang@sh [转载时请以超链接形式标明文章] 链接:http://www.cnblogs.com/david-zhang-index/p/4166846.html 本文适用RH ...
- Flutter实战视频-移动电商-46.详细页_自定义TabBar Widget
46.详细页_自定义TabBar Widget 主要实现详情和评论的tab provide定义变量 自己做一个tab然后用provide去控制 定义两个变量来判断是左侧选中了还是右侧选中了.并定义一个 ...
- ASP.NET Core会议管理平台实战_1、开篇介绍
用到四个数据库
- python3 封装之property 多态 绑定方法classmethod 与 非绑定方法 staticmethod
property 特性 什么是特性property property 是一种特殊的属性,访问它时会执行一段功能(函数),然后返回值 例如 BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而 ...