python---Django中模型类中Meta元对象了解
Django中模型类中Meta元对象了解
1.使用python manage.py shell 进入编辑命令行模式,可以直接进入项目(为我们配置好了环境)
python manage.py shell
2.对于元类数据的获取,需要使用_meta获取
>>> models.CustumerInfo._meta
<Options for CustumerInfo>
3.几个重要属性
app_label:表示它属于哪个应用 models.CustumerInfo._meta.app_label ---> 'repository' 在repository应用下面 model_name:获取模型名(表对应的类名)models.CustumerInfo._meta.model_name ---> 'custumerinfo' #小写 label:获取的是repository.CustumerInfo #分大小写 label_lower:不区分大小写 db_table:获取完整表名,含数据库 repository_custumerinfo
其他可以根据在元类中所设置的去获取数据:更多属性可看https://blog.csdn.net/gavinking0110/article/details/53126203
4.通过元类获取choice字段值
(1)补充:如何获取含choice属性的字段值对应的字符串(重点)
status_choices = ((,"未报名"),(,"已报名"),(,"已退学"))
status = models.SmallIntegerField(choices=status_choices)
source_choices = (
(,'QQ群'),
(,"51CTO"),
(,"百度推广"),
(,"知乎"),
(,"转介绍"),
(,"其他")
)
source = models.SmallIntegerField(choices=source_choices)
source 字段
.首先获取当前对象
>>> a = models.CustumerInfo.objects.last()
>>> a
<CustumerInfo: 三狗子> .使用方法get_字段名_display()获取对应字符串
>>> a.get_status_display()
'未报名'
>>> a.get_source_display()
'其他'
这种方法也可以动态获取对应的字符串:
动态拼接:获取方法名
>>> hasattr(a,"get_status_display")
True
>>> hasattr(a,"get_name_display")
False 根据返回的bool值,去判断是否去调用对应的方法 >>> getattr(a,"get_status_display")()
'未报名'
但是上面只能获取到当前选中的值得对应字符串,如何去获取所有可选选项,一种是去model模型类获取该属性。若是上面这个不允许,那我们可以使用元类的属性去获取
(2)注意:每一个字段,都是一个对象。
models.CustumerInfo._meta.fields
>>> models.CustumerInfo._meta.fields
(<django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: na
me>, <django.db.models.fields.SmallIntegerField: contact_type>, <django.db.model
s.fields.CharField: contact>, <django.db.models.fields.SmallIntegerField: source
>, <django.db.models.fields.related.ForeignKey: referral_from>, <django.db.model
s.fields.TextField: consult_content>, <django.db.models.fields.SmallIntegerField
: status>, <django.db.models.fields.related.ForeignKey: consultant>, <django.db.
models.fields.DateField: date>)
输出的所有字段对象
通过get_field(字段名)获取当前字段对象
>>> a = models.CustumerInfo._meta.get_field("source")
>>> a
<django.db.models.fields.SmallIntegerField: source>
>>> a = models.CustumerInfo._meta.get_field("name")
>>> a
<django.db.models.fields.CharField: name>
获取到字段对象后可以去获取字段的属性(对于我们所需的字段中就含有choice属性)
>>> dir(a)
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__ha
sh__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__red
uce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__
subclasshook__', '__weakref__', '_check_backend_specific_checks', '_check_choice
s', '_check_db_index', '_check_deprecation_details', '_check_field_name', '_chec
k_max_length_attribute', '_check_null_allowed_for_primary_keys', '_clear_cached_
lookups', '_description', '_error_messages', '_get_default', '_get_flatchoices',
'_get_lookup', '_get_val_from_obj', '_unique', '_unregister_lookup', '_validato
rs', '_verbose_name', 'attname', 'auto_created', 'auto_creation_counter', 'blank
', 'cached_col', 'check', 'choices', 'class_lookups', 'clean', 'clone', 'column'
, 'concrete', 'contribute_to_class', 'creation_counter', 'db_check', 'db_column'
, 'db_index', 'db_parameters', 'db_tablespace', 'db_type', 'db_type_suffix', 'de
construct', 'default', 'default_error_messages', 'default_validators', 'descript
ion', 'editable', 'empty_strings_allowed', 'empty_values', 'error_messages', 'fl
atchoices', 'formfield', 'get_attname', 'get_attname_column', 'get_cache_name',
'get_choices', 'get_col', 'get_db_converters', 'get_db_prep_save', 'get_db_prep_
value', 'get_default', 'get_filter_kwargs_for_object', 'get_internal_type', 'get
_lookup', 'get_lookups', 'get_pk_value_on_save', 'get_prep_value', 'get_transfor
m', 'has_default', 'help_text', 'hidden', 'is_relation', 'many_to_many', 'many_t
o_one', 'max_length', 'merge_dicts', 'model', 'name', 'null', 'one_to_many', 'on
e_to_one', 'pre_save', 'primary_key', 'register_lookup', 'rel', 'rel_db_type', '
related_model', 'remote_field', 'run_validators', 'save_form_data', 'select_form
at', 'serialize', 'set_attributes_from_name', 'system_check_deprecated_details',
'system_check_removed_details', 'to_python', 'unique', 'unique_for_date', 'uniq
ue_for_month', 'unique_for_year', 'validate', 'validators', 'value_from_object',
'value_to_string', 'verbose_name']
dir(字段对象),获取字段对象的所有属性
>>> a = models.CustumerInfo._meta.get_field("status")
>>> a.choices
((, '未报名'), (, '已报名'), (, '已退学'))
#对于含有choices,输出是有值的
>>> a = models.CustumerInfo._meta.get_field("name")
>>> a.choices
[]
#对于不含choices,输出为空
可以通过字段对象获取与之关联的表(外键或者多对多)
>>> a = CustumerInfo._meta.get_field("consult_courses") #获取字段对象
>>> a.rel.to
<class 'repository.models.Course'> #获取对应的关联表
>>> a.related_model
<class 'repository.models.Course'> #或者使用related_model属性获取
(3)对于外键,我们想要获取到像choice一样的数据,可以使用get_choices()方法
>>> a = models.CustumerInfo._meta.get_field("consultant") #consultant是外键
>>> a
<django.db.models.fields.related.ForeignKey: consultant>
>>> a.choices #其中choices是空,但是我们想要获取数据,类似于choices,可以用于筛选
[]
>>> a.get_choices() #使用get_choices()方法用于获取外键数据,形成类似于select标签
[('', '---------'), (, '宁静致远'), (, '三少爷的剑')]
注意:对于原来的含有choice属性的字段,也可以使用get_choices()方法,来获取。不过就也是在前面多了一个选项(类似于请选择的意思)
>>> a = models.CustumerInfo._meta.get_field("status") #status含有choice属性
>>> a.choices
((, '未报名'), (, '已报名'), (, '已退学'))
>>> a.get_choices()
[('', '---------'), (, '未报名'), (, '已报名'), (, '已退学')]
注意对于其他字段是不含有get_choices()方法,会报错。所以不要乱用
>>> a = models.CustumerInfo._meta.get_field("name") #CharFields
>>> a.get_choices()
Traceback (most recent call last):
File "<console>", line , in <module>
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-p
ackages\django\db\models\fields\__init__.py", line 811, in get_choices
rel_model = self.remote_field.model
AttributeError: 'NoneType' object has no attribute 'model'
(4)获取字段对象的类型get_internal_type()
>>> a = models.CustumerInfo._meta.get_field("name")
>>> a.get_internal_type()
'CharField'
>>> a = models.CustumerInfo._meta.get_field("date")
>>> a.get_internal_type()
'DateField'
(5)上面是单个字段的关联表,那么如何获取这张表的外键关联(一对多,一对一,多对多)?
>>> a = CustumerInfo._meta #这张表的元类 >>> for item in a.related_objects: #是获取所有由其他表来关联自己的那些表,也含有多对多关联信息 反向关联_set
... print(item)
...
<ManyToOneRel: repository.custumerinfo> #每条都是一个外键字段信息,可以使用get_internal_type获取其前面的类型:ManyToOneRel:注意也会有ManyToManyRel多对多关联
<ManyToOneRel: repository.custumerfollowup>
<ManyToOneRel: repository.student> >>> for item in a.fields_map.items(): #不止其他表来关联自己,还有自己去关联其他表
... print(item)
...
('student', <ManyToOneRel: repository.student>)
('CustumerInfo_consult_courses+', <ManyToOneRel: repository.custumerinfo_consult_courses>) #自己表去关联其他表,后面有个+
('custumerfollowup', <ManyToOneRel: repository.custumerfollowup>)
('custumerinfo', <ManyToOneRel: repository.custumerinfo>)
补充:ManyToOneRel对象
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__form
at__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__in
it__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__r
educe_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook
__', '__weakref__', 'auto_created', 'concrete', 'db_type', 'editable', 'field',
'field_name', 'get_accessor_name', 'get_cache_name', 'get_choices', 'get_extra_r
estriction', 'get_internal_type', 'get_joining_columns', 'get_lookup', 'get_path
_info', 'get_related_field', 'hidden', 'is_hidden', 'is_relation', 'limit_choice
s_to', 'many_to_many', 'many_to_one', 'model', 'multiple', 'name', 'null', 'on_d
elete', 'one_to_many', 'one_to_one', 'parent_link', 'related_model', 'related_na
me', 'related_query_name', 'remote_field', 'set_field_name', 'symmetrical', 'tar
get_field', 'to']
其含有的所有属性
>>> a = CustumerInfo._meta.related_objects
>>> a
(<ManyToOneRel: repository.custumerinfo>, <ManyToOneRel: repository.custumerfoll
owup>, <ManyToOneRel: repository.student>)
>>> a[]
<ManyToOneRel: repository.custumerinfo> -------------------------------------------------------------
主要属性:
>>> a[].name #该表的表名 根据这个可以在主表中对这张表进行反向关联_set
'custumerinfo' >>> a[].field_name #主键字段名
'id' >>> a[].field #field是外键字段
<django.db.models.fields.related.ForeignKey: referral_from>
>>> a[].field
<django.db.models.fields.related.ForeignKey: customer>
注意:上面我们是直接使用类去调用元类,其实也是可以使用对象去调用元类,一样
类调用:
>>> a = CustumerInfo._meta
>>> a.related_objects
(<ManyToOneRel: repository.custumerinfo>, <ManyToOneRel: repository.custumerfoll
owup>, <ManyToOneRel: repository.student>) 对象调用:
>>> a = CustumerInfo.objects.all()[]
>>> a
<CustumerInfo: 张三>
>>> a._meta
<Options for CustumerInfo>
>>> a._meta.related_objects
(<ManyToOneRel: repository.custumerinfo>, <ManyToOneRel: repository.custumerfoll
owup>, <ManyToOneRel: repository.student>)
总结:
_meta.fields 获取所有字段
_meta.fields_map/related_objects获取反向关联,related_objects中只有反向关联,fields_map有正向关联,不过字段名为(表名_字段名+).例如:'CustumerInfo_consult_courses+'
_meta.many_to_many/local_many_to_many获取多对多关联
python---Django中模型类中Meta元对象了解的更多相关文章
- Python 装饰器装饰类中的方法
title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...
- django定义模型类-14
目录 1. 定义 字段类型 约束类型 django的模型类定义在应用下的 models.py 文件中. 模型类继承自 django.db.models 包下的 Model 类. 新创建应用 book ...
- django定义模型类
模型类被定义在应用文件夹下的model.py中 模型类必须继承Django的models.Model类 属性名不能用连续的两条下划线__ 主键:primary key,简写 pk 不需要主动定义,dj ...
- c++中在一个类中定义另一个只有带参数构造函数的类的对象
c++中在一个类中定义另一个只有带参数构造函数的类的对象,编译通不过 #include<iostream> using namespace std; class A { public: ...
- Java中主类中定义方法加static和不加static的区别
Java中主类中定义方法加static和不加static的区别(前者可以省略类名直接在主方法调用(类名.方法),后者必须先实例化后用实例调用) 知识点:1.Getter and Setter 的应用 ...
- C++中若类中没有默认构造函数,如何使用对象数组
前言: 如果定义一个类,有其默认的构造函数,则使用new动态实例化一个对象数组,不是件难事,如下代码: #include <memory> #include <iostream> ...
- Qt 在相同的线程中可以在信号中传递未注册的元对象,在非相同线程中则不能传递未测试的对象,为什么呢?
有兄台知道可以在留言告诉我,万分感谢!!! 需求:需要在多线程中传递未注册的非元对象数据,时间紧急,无法及时更改该传递的数据为元对象,非继承 QObject 这里采用指针方式传递,同时把传递的局部变量 ...
- django之模型类在视图中的应用
一:模型类直接从把前端表单传入的值,进行存储. @csrf_exempt def regist(request): if request.method == 'POST': form = UserFo ...
- Django中模型层中ORM的单表操作
ORM概念: MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员 ...
随机推荐
- 20162314 《Program Design & Data Structures》Learning Summary Of The Second Week
20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Second Week ...
- Linux环境下服务器环境搭建-mysql
下载对应版本的mysql.rpm(Linux 6 安装el6 Linux 7 安装el7) 安装环境 centos 7,安装版本mysql57-community-release-el7-9.noar ...
- Java 面试 --- 3
上一篇,我们给出了大概35个题目,都是基础知识,有童鞋反映题目过时了,其实不然,这些是基础中的基础,但是也是必不可少的,面试题目中还是有一些基础题目的,我们本着先易后难的原则,逐渐给出不同级别的题目, ...
- 【Coursera】基于朴素贝叶斯的中文多分类器
一.算法说明 为了便于计算类条件概率\(P(x|c)\),朴素贝叶斯算法作了一个关键的假设:对已知类别,假设所有属性相互独立. 当使用训练完的特征向量对新样本进行测试时,由于概率是多个很小的相乘所得, ...
- python learning Functional Programming.py
print(abs(-10)) # 函数可以是变量 f = abs f(-10) def add(x,y,f): return f(x) + f(y) x = -5 y = 6 f = abs # 简 ...
- Visual Studio 中配置openCV问题
1. 首先强调一点:VS与openCV的版本对应问题,一般而言,openCV对于VS采用向下的支持方式: vc6 -> VS6.0 vc7.0 -> VS2002 vc7.1 -> ...
- Week4-作业1:《构建之法》第四章、第十七章 阅读笔记与思考
第四章 两人合作 这一章是讲述了两人结对编程的一些东西,包括一些代码的规范,还有结对编程的优点.怎么做.以及一些注意事项. 1.“错误处理 当程序的主要功能实现后,一些程序员会乐观地估计只需要另外 ...
- Rsyslog日志服务搭建
rsyslog是比syslog功能更强大的日志记录系统,可以将日志输出到文件,数据库和其它程序.Centos 6.x默认的rsyslog版本是5.x. 网上关于rsyslog的安装配置文档倒是不少,但 ...
- linux下 XGCOM串口助手的安装
源码下载:http://code.google.com/p/xgcom/ 也可以自己搜索下载 首先先安装依赖库,直接运行命令 #sudo apt-get install libglib2.0- ...
- mysql索引的优化
MySQL索引的优化 上面都在说使用索引的好处,但过多的使用索引将会造成滥用.因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT.UPDATE和DEL ...