zoukankan      html  css  js  c++  java
  • 西游之路——python全栈——Django中模型类中Meta元对象了解

    目录

    Django中模型类中Meta元对象了解
      1.使用python manage.py shell 进入编辑命令行模式,可以直接进入项目(为我们配置好了环境)
      2.对于元类数据的获取,需要使用_meta获取
      3.几个重要属性
       4.通过元类获取choice字段值

    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)

    ================

     1 source_choices = (
     2         (0,'QQ群'),
     3         (1,"51CTO"),
     4         (2,"百度推广"),
     5         (3,"知乎"),
     6         (4,"转介绍"),
     7         (5,"其他")
     8     )
     9     source = models.SmallIntegerField(choices=source_choices)
    10 
    11 source 字段
    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
    1 >>> models.CustumerInfo._meta.fields
    2 (<django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: na
    3 me>, <django.db.models.fields.SmallIntegerField: contact_type>, <django.db.model
    4 s.fields.CharField: contact>, <django.db.models.fields.SmallIntegerField: source
    5 >, <django.db.models.fields.related.ForeignKey: referral_from>, <django.db.model
    6 s.fields.TextField: consult_content>, <django.db.models.fields.SmallIntegerField
    7 : status>, <django.db.models.fields.related.ForeignKey: consultant>, <django.db.
    8 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属性)

     1 >>> dir(a)
     2 ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__dir__',
     3 '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__ha
     4 sh__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__red
     5 uce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__
     6 subclasshook__', '__weakref__', '_check_backend_specific_checks', '_check_choice
     7 s', '_check_db_index', '_check_deprecation_details', '_check_field_name', '_chec
     8 k_max_length_attribute', '_check_null_allowed_for_primary_keys', '_clear_cached_
     9 lookups', '_description', '_error_messages', '_get_default', '_get_flatchoices',
    10  '_get_lookup', '_get_val_from_obj', '_unique', '_unregister_lookup', '_validato
    11 rs', '_verbose_name', 'attname', 'auto_created', 'auto_creation_counter', 'blank
    12 ', 'cached_col', 'check', 'choices', 'class_lookups', 'clean', 'clone', 'column'
    13 , 'concrete', 'contribute_to_class', 'creation_counter', 'db_check', 'db_column'
    14 , 'db_index', 'db_parameters', 'db_tablespace', 'db_type', 'db_type_suffix', 'de
    15 construct', 'default', 'default_error_messages', 'default_validators', 'descript
    16 ion', 'editable', 'empty_strings_allowed', 'empty_values', 'error_messages', 'fl
    17 atchoices', 'formfield', 'get_attname', 'get_attname_column', 'get_cache_name',
    18 'get_choices', 'get_col', 'get_db_converters', 'get_db_prep_save', 'get_db_prep_
    19 value', 'get_default', 'get_filter_kwargs_for_object', 'get_internal_type', 'get
    20 _lookup', 'get_lookups', 'get_pk_value_on_save', 'get_prep_value', 'get_transfor
    21 m', 'has_default', 'help_text', 'hidden', 'is_relation', 'many_to_many', 'many_t
    22 o_one', 'max_length', 'merge_dicts', 'model', 'name', 'null', 'one_to_many', 'on
    23 e_to_one', 'pre_save', 'primary_key', 'register_lookup', 'rel', 'rel_db_type', '
    24 related_model', 'remote_field', 'run_validators', 'save_form_data', 'select_form
    25 at', 'serialize', 'set_attributes_from_name', 'system_check_deprecated_details',
    26  'system_check_removed_details', 'to_python', 'unique', 'unique_for_date', 'uniq
    27 ue_for_month', 'unique_for_year', 'validate', 'validators', 'value_from_object',
    28  'value_to_string', 'verbose_name']
    29 
    30 dir(字段对象),获取字段对象的所有属性
    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:UsersAdministratorAppDataLocalProgramsPythonPython35libsite-p
    ackagesdjangodbmodelsfields\__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对象

     1 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__form
     2 at__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__in
     3 it__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__r
     4 educe_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook
     5 __', '__weakref__', 'auto_created', 'concrete', 'db_type', 'editable', 'field',
     6 'field_name', 'get_accessor_name', 'get_cache_name', 'get_choices', 'get_extra_r
     7 estriction', 'get_internal_type', 'get_joining_columns', 'get_lookup', 'get_path
     8 _info', 'get_related_field', 'hidden', 'is_hidden', 'is_relation', 'limit_choice
     9 s_to', 'many_to_many', 'many_to_one', 'model', 'multiple', 'name', 'null', 'on_d
    10 elete', 'one_to_many', 'one_to_one', 'parent_link', 'related_model', 'related_na
    11 me', 'related_query_name', 'remote_field', 'set_field_name', 'symmetrical', 'tar
    12 get_field', 'to']
    13 
    14 其含有的所有属性
    其含有的所有属性

    ===================

    复制代码
    >>> 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获取多对多关联

  • 相关阅读:
    UIWebView长按弹出菜单显示英文解决办法
    远程推送不能获取token的原因(证书配置正确)
    汉字转拼音 汉字排序功能
    旋转360度动画
    获取wifi列表
    openssl生成私钥公钥的步骤
    JAVA后台框架优化之日志篇
    react native学习资料
    RAP, 高效前后端联调框架,接口文档管理工具
    【JMeter】JMeter在linux下运行
  • 原文地址:https://www.cnblogs.com/Lujun1028/p/9960715.html
Copyright © 2011-2022 走看看