Django中模型类中Meta元对象了解

1.使用python manage.py shell 进入编辑命令行模式,可以直接进入项目(为我们配置好了环境)

python manage.py shell

2.对于元类数据的获取,需要使用_meta获取

>>> models.CustumerInfo._meta
<Options for CustumerInfo>
dir(models.CustumerInfo._meta)获取该数据表所有的元类属性

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元对象了解的更多相关文章

  1. Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  2. django定义模型类-14

    目录 1. 定义 字段类型 约束类型 django的模型类定义在应用下的 models.py 文件中. 模型类继承自 django.db.models 包下的 Model 类. 新创建应用 book ...

  3. django定义模型类

    模型类被定义在应用文件夹下的model.py中 模型类必须继承Django的models.Model类 属性名不能用连续的两条下划线__ 主键:primary key,简写 pk 不需要主动定义,dj ...

  4. c++中在一个类中定义另一个只有带参数构造函数的类的对象

    c++中在一个类中定义另一个只有带参数构造函数的类的对象,编译通不过 #include<iostream> using namespace std; class A { public:  ...

  5. Java中主类中定义方法加static和不加static的区别

     Java中主类中定义方法加static和不加static的区别(前者可以省略类名直接在主方法调用(类名.方法),后者必须先实例化后用实例调用) 知识点:1.Getter and Setter 的应用 ...

  6. C++中若类中没有默认构造函数,如何使用对象数组

    前言: 如果定义一个类,有其默认的构造函数,则使用new动态实例化一个对象数组,不是件难事,如下代码: #include <memory> #include <iostream> ...

  7. Qt 在相同的线程中可以在信号中传递未注册的元对象,在非相同线程中则不能传递未测试的对象,为什么呢?

    有兄台知道可以在留言告诉我,万分感谢!!! 需求:需要在多线程中传递未注册的非元对象数据,时间紧急,无法及时更改该传递的数据为元对象,非继承 QObject 这里采用指针方式传递,同时把传递的局部变量 ...

  8. django之模型类在视图中的应用

    一:模型类直接从把前端表单传入的值,进行存储. @csrf_exempt def regist(request): if request.method == 'POST': form = UserFo ...

  9. Django中模型层中ORM的单表操作

    ORM概念: MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员 ...

随机推荐

  1. 20162327WJH第一次实验——线性结构

    20162327WJH第一次实验--线性结构 实 验 报 告 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 2分 指导教师:娄嘉鹏 王志强 ...

  2. 【每日scrum】第一次冲刺day5

    请教以前做过类似软件的同学,受益匪浅,启发自己

  3. spring冲刺第六天

    昨天编写地图代码,完善地图界面,使其变得美观. 今天把地图界面初步完成,和其他团队成员的成果进行结合,整合人物和地图代码. 遇到的问题:在整合时遇到的问题比较多,今天没有整合成功.

  4. 《大象Think in UML》阅读笔记之一

    Think in UML这一书以UML为载体,将面向对象的分析设计思想巧妙地融合在建模UML当中,通过一些实例将软件系统的开发过程中的一些知识有机地结合起来.全书共分为四篇:准备篇.基础篇.进阶篇和总 ...

  5. Internet History, Technology and Security (Week3)

    Week3. Welcome to week 3! This is our fourth and final week of History where we make the connection ...

  6. VR论文调研

    IEEE VR 2018 1.Avatars and Virtual Humans--人物和虚拟人物 2.Augmented Reality--增强现实 3.Body and Mind--人体和思想( ...

  7. Windows 常见错误总结

    本篇主要记录Windows 系统使用中存在的问题和解决方案,会保持持续更新...(若你们遇到的问题或有更好的解决方法,还望在评论区留言,谢谢) 1.win10 unable to save C:\wi ...

  8. RHEL/Centos下VSFTPD服务器搭建

    目的 Linux下安装配置vsfptd服务器,并通过客户端验证. 环境 Centos 6 局域网 内容 配置Vsftpd服务器:实现匿名用户.本地用户和虚拟用户登录的配置.匿名用户可以上载文件,上载后 ...

  9. 014 Java的反射机制

    作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...

  10. mysql中while循环以及变量声明以及dilimiter

    首先我们查看一个正确的完整的一个存储过程 ①其中delimiter命令解释如下:默认情况下,delimiter是分号:.在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令 ...