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 = ((
0,
"未报名"),(
1,
"已报名"),(
2,
"已退学"))
status = models.SmallIntegerField(choices=status_choices)
source_choices =
(
(0,
'QQ群'),
(1,
"51CTO"),
(2,
"百度推广"),
(3,
"知乎"),
(4,
"转介绍"),
(5,
"其他")
)
source = models.SmallIntegerField(choices=source_choices)
source 字段
1.首先获取当前对象
>>> a =
models.CustumerInfo.objects.last()
>>>
a
<CustumerInfo: 三狗子>
2.使用方法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
((0,
'未报名'), (
1,
'已报名'), (
2,
'已退学'))
#对于含有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标签
[('',
'---------'), (
1,
'宁静致远'), (
2,
'三少爷的剑')]
注意:对于原来的含有choice属性的字段,也可以使用get_choices()方法,来获取。不过就也是在前面多了一个选项(类似于请选择的意思)
>>> a = models.CustumerInfo._meta.get_field(
"status") #status含有choice属性
>>>
a.choices
((0,
'未报名'), (
1,
'已报名'), (
2,
'已退学'))
>>>
a.get_choices()
[('',
'---------'), (
0,
'未报名'), (
1,
'已报名'), (
2,
'已退学')]
注意对于其他字段是不含有get_choices()方法,会报错。所以不要乱用
>>> a = models.CustumerInfo._meta.get_field(
"name") #CharFields
>>>
a.get_choices()
Traceback (most recent call last):
File "<console>", line
1,
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[
0]
<ManyToOneRel: repository.custumerinfo>
-------------------------------------------------------------
主要属性:
>>> a[
0].name #该表的表名 根据这个可以在主表中对这张表进行反向关联_set
'custumerinfo'
>>> a[
0].field_name #主键字段名
'id'
>>> a[
0].field #field是外键字段
<django.db.models.fields.related.ForeignKey: referral_from>
>>> a[
1].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()[
0]
>>>
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获取多对多关联
转载于:https://www.cnblogs.com/ssyfj/p/9093503.html