链条传动

砥砺前行,不忘初心!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
http://www.cnblogs.com/wupeiqi/articles/5246483.html

model,ORM
    1、创建数据库表
        创建class -> 在DB中自动生成表

        a. 创建class:
            mysite
                app01
                    - models.py
                        from django.db import models

                        class UserType(models.Model):
                            type_name = models.CharField(max_length=32)

                            # 在admin中默认显示对象,要想显示type_name,需要使用__str__方法
                            def __str__(self):
                                return self.type_name

                        class UserInfo(models.Model):
                            name = models.CharField(max_length=30) # 数据库中类型:string
                            email = models.EmailField()            # 数据库中类型:string,email对数据库没有用,只是用来帮助Django在admin中做输入验证
                            memo = models.TextField()              # 数据库中类型:textpyt
                            img = models.ImageField(upload_to='upload')  # 上传的文件存放到upload文件夹下

                            # ForeignKey:外键,一对多关系。
                            # null=True表示数据库字段可以为空 blank=True表示Django中admin可不进行为空验证
                            user_type = models.ForeignKey(UserType, null=True, blank=True)  # UserType也可以写成字符串形式:"UserType",这样就不要求UserType类必须在UserInfo上面了


        b. 注册到Django的admin中
            mysite
                app01
                    -admin.py
                        from django.contrib import admin
                        from app01 import models

                        # 将models中创建的表添加到Django的admin中,用于进行后台操作
                        admin.site.register(models.UserType),
                        admin.site.register(models.UserInfo),

        c. 生成表
            python manage.py makemigrations
            python manage.py migrate

        d. 创建超级用户
           python manage.py createsuperuser


    2、Django表字段和方法
        字段
            1、models.AutoField  自增列 = int(11)
              如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
            2、models.CharField  字符串字段
              必须 max_length 参数
            3、models.BooleanField  布尔类型=tinyint(1)
              不能为空,Blank=True
            4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
                input:  12,345,989871234,
              继承CharField,所以必须 max_lenght 参数
            5、models.DateField  日期类型 date----- 日期格式      YYYY-MM-DD
              对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
            6、models.DateTimeField  日期类型 datetime------ 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
              同DateField的参数
            7、models.Decimal  十进制小数类型 = decimal
              必须指定整数位max_digits和小数位decimal_places
            8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
              对字符串进行正则表达式
            9、models.FloatField  浮点类型 = double
            10、models.IntegerField  整形
            11、models.BigIntegerField  长整形
              integer_field_ranges = {
                'SmallIntegerField': (-32768, 32767),
                'IntegerField': (-2147483648, 2147483647),
                'BigIntegerField': (-9223372036854775808, 9223372036854775807),
                'PositiveSmallIntegerField': (0, 32767),
                'PositiveIntegerField': (0, 2147483647),
              }
            12、models.IPAddressField  字符串类型(ip4正则表达式)---Django后面的版本中会被GenericIPAddressField取代
            13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
              参数protocol可以是:both、ipv4、ipv6
              验证时,会根据设置报错
            14、models.NullBooleanField  允许为空的布尔类型
            15、models.PositiveIntegerFiel  正Integer
            16、models.PositiveSmallIntegerField  正smallInteger
            17、models.SlugField  减号、下划线、字母、数字
            18、models.SmallIntegerField  数字
              数据库中的字段有:tinyint、smallint、int、bigint
            19、models.TextField  字符串=longtext
            20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
            21、models.URLField  字符串,地址正则表达式
            22、models.BinaryField  二进制

            23、models.ImageField   图片    数据库中:字符串。保存的是路径----Django的admin中会自动出现上传图片的功能
            24、models.FilePathField 文件   数据库中:字符串。保存的是路径

        方法:
            null                数据库中字段是否可以为空
            db_column           数据库中字段的列名
            db_tablespace
            default             数据库中字段的默认值
            primary_key         数据库中字段是否为主键
            db_index            数据库中字段是否可以建立索引
            unique              数据库中字段是否可以建立唯一索引
            unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
            unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
            unique_for_year     数据库中字段【年】部分是否可以建立唯一索引
            upload_to='upload'  上传的文件存放到upload文件夹下

            verbose_name        Admin中显示的字段名称
            blank               Admin中是否允许用户输入为空
            editable            Admin中是否可以编辑
            help_text           Admin中该字段的提示信息
            choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                                如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)---显示的是名称,数据库中存储的是0或1

            error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                                字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                                如:{'null': "不能为空.", 'invalid': '格式错误'}

            validators          自定义错误验证(列表类型),从而定制想要的验证规则
                                from django.core.validators import RegexValidator
                                from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                                MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                                如:
                                    test = models.CharField(
                                        max_length=32,
                                        error_messages={
                                            'c1': '优先错信息1',
                                            'c2': '优先错信息2',
                                            'c3': '优先错信息3',
                                        },
                                        validators=[
                                            RegexValidator(regex='root_\d+', message='错误了', code='c1'),
                                            RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
                                            EmailValidator(message='又错误了', code='c3'), ]
                                    )

    3.Django表类型:
        a. 单表
        b. 一对多:models.ForeignKey(其他表)
        c. 多对多:models.ManyToManyField(其他表)
            mysite
                app01
                    - models.py
                        # 多对多关系
                        # 第一种方式:自己创建第三方表
                        # class BoyToGirl(models.Model):
                        #     boy = models.ForeignKey('Boy')
                        #     girl = models.ForeignKey('Girl')


                        class Boy(models.Model):
                            name = models.CharField(max_length=32)


                        class Girl(models.Model):
                            name = models.CharField(max_length=32)

                            f = models.ManyToManyField(Boy)  # 多对多第二种方式,会自动生成第三张表

        d. 一对一:models.OneToOneField(其他表)

        e. 表类型应用场景:
            一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
                例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
            多对多:在某表中创建一行数据是,有一个可以多选的下拉框
                例如:创建用户信息,需要为用户指定多个爱好
            一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了
                例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据

        f. 不同类型表的字段和方法
            ForeignKey(ForeignObject) # ForeignObject(RelatedField)
                        to,                         # 要进行关联的表名
                        to_field=None,              # 要关联的表中的字段名称
                        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为
                                                        - models.CASCADE,删除关联数据,与之关联也删除
                                                        - models.DO_NOTHING,删除关联数据,引发错误IntegrityError
                                                        - models.PROTECT,删除关联数据,引发错误ProtectedError
                                                        - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
                                                        - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
                                                        - models.SET,删除关联数据,
                                                                      a. 与之关联的值设置为指定值,设置:models.SET(值)
                                                                      b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

                                                                        def func():
                                                                            return 10

                                                                        class MyModel(models.Model):
                                                                            user = models.ForeignKey(
                                                                                to="User",
                                                                                to_field="id"
                                                                                on_delete=models.SET(func),)
                        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
                        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
                        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                                    # 如:
                                                            - limit_choices_to={'nid__gt': 5}
                                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                                            from django.db.models import Q
                                                            - limit_choices_to=Q(nid__gt=10)
                                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
                        db_constraint=True          # 是否在数据库中创建外键约束
                        parent_link=False           # 在Admin中是否显示关联数据


            OneToOneField(ForeignKey)
                        to,                         # 要进行关联的表名
                        to_field=None               # 要关联的表中的字段名称
                        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为

                                                    ###### 对于一对一 ######
                                                    # 1. 一对一其实就是 一对多 + 唯一索引
                                                    # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
                                                    # 如下会在A表中额外增加一个c_ptr_id列且唯一:
                                                            class C(models.Model):
                                                                nid = models.AutoField(primary_key=True)
                                                                part = models.CharField(max_length=12)

                                                            class A(C):
                                                                id = models.AutoField(primary_key=True)
                                                                code = models.CharField(max_length=1)

            ManyToManyField(RelatedField)
                        to,                         # 要进行关联的表名
                        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
                        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
                        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                                    # 如:
                                                            - limit_choices_to={'nid__gt': 5}
                                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                                            from django.db.models import Q
                                                            - limit_choices_to=Q(nid__gt=10)
                                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
                        symmetrical=None,           # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
                                                    # 做如下操作时,不同的symmetrical会有不同的可选字段
                                                        models.BB.objects.filter(...)

                                                        # 可选字段有:code, id, m1
                                                            class BB(models.Model):

                                                            code = models.CharField(max_length=12)
                                                            m1 = models.ManyToManyField('self',symmetrical=True)

                                                        # 可选字段有: bb, code, id, m1
                                                            class BB(models.Model):

                                                            code = models.CharField(max_length=12)
                                                            m1 = models.ManyToManyField('self',symmetrical=False)

                        through=None,               # 自定义第三张表时,使用字段用于指定关系表
                        through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
                                                        from django.db import models

                                                        class Person(models.Model):
                                                            name = models.CharField(max_length=50)

                                                        class Group(models.Model):
                                                            name = models.CharField(max_length=128)
                                                            members = models.ManyToManyField(
                                                                Person,
                                                                through='Membership',
                                                                through_fields=('group', 'person'),
                                                            )

                                                        class Membership(models.Model):
                                                            group = models.ForeignKey(Group, on_delete=models.CASCADE)
                                                            person = models.ForeignKey(Person, on_delete=models.CASCADE)
                                                            inviter = models.ForeignKey(
                                                                Person,
                                                                on_delete=models.CASCADE,
                                                                related_name="membership_invites",
                                                            )
                                                            invite_reason = models.CharField(max_length=64)
                        db_constraint=True,         # 是否在数据库中创建外键约束
                        db_table=None,              # 默认创建第三张表时,数据库中表的名称


    4. Django数据库表操作
        a. 基本操作
                #
                #
                # models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs

                # obj = models.Tb1(c1='xx', c2='oo')
                # obj.save()

                #
                #
                # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
                # models.Tb1.objects.all()               # 获取全部
                # models.Tb1.objects.filter(name='seven') # 获取指定条件的数据

                #
                #
                # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

                #
                # models.Tb1.objects.filter(name='seven').update(gender='0')  # 将指定条件的数据更新,均支持 **kwargs

                # obj = models.Tb1.objects.get(id=1)
                # obj.c1 = '111'
                # obj.save()                                                 # 修改单条数据


        b. 查询说明
                obj = model.UserInfo.objects.filter(name='alex')   # 获取的是一个数据列表
                print obj.query  # 打印obj对应的sql语句
                obj是一个queryset类型 -> python,Django的类
                [obj1,obj2,obj3]----obj内部的数据是一个个对象

                obj1 = model.UserInfo.objects.filter(name='alex').values('id','email')  # 获取的是一个数据列表
                # select id from userinfo where name = 'alex'
                obj1也是一个queryset类型 -> python,Django的类
                [{'id':1},{'id': 2},]---obj1内部的数据是一个个字典

                obj2 = model.UserInfo.objects.filter(name='alex').value_list('id','email')  # 获取的是一个数据列表
                # select id from userinfo where name = 'alex'
                obj也是一个queryset类型 -> python,Django的类
                [(1,'1@qq.com'),(2,'alex@11.com'),]----bj2内部的数据是一个个元组

 

posted on 2017-01-05 16:51  链条君  阅读(284)  评论(0编辑  收藏  举报