s4 model orm

- ORM操作表

- 单表增删改查

    # models.py
    
        from django.db import models

        class UserGroup(models.Model):
            """
            部门
            """
            title = models.CharField(max_length=32)
        """
            models.UserGroup.objects.create(title='销售部')
            models.UserGroup.objects.filter(id=2).delete()
            models.UserGroup.objects.filter(id=2).update(title='公关部')
            group_list = models.UserGroup.objects.all()
            group_list = models.UserGroup.objects.filter(id=1)
            group_list = models.UserGroup.objects.filter(id__gt=1)  #大于
            group_list = models.UserGroup.objects.filter(id__lt=1)  #小于
        """

        class UserInfo(models.Model):
            """
            员工
            """
            nid = models.BigAutoField(primary_key=True)
            user = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
            age = models.IntegerField(default=1)
            # ug_id
            ug = models.ForeignKey("UserGroup",null=True)
    
    # views.py
    
        from app01 import models
        def index(request):
            # 增删改查
            
            # 新增
            # models.UserGroup.objects.create(title='销售部')
            # models.UserInfo.objects.create(user='root',password='pwd',age=18,ug_id=1)
            
            # 查找
            # group_list = models.UserGroup.objects.all()
            # group_list = models.UserGroup.objects.filter(id=1)
            # group_list = models.UserGroup.objects.filter(id__gt=1)
            # group_list = models.UserGroup.objects.filter(id__lt=1)
                        
            # models.UserInfo.objects.all()
            
            # group_list QuerySet类型(列表)
            # QuerySet类型[obj,obj,obj]
            # print(group_list)
            # for row in group_list:
            #     print(row.id,row.title)


            # 删除
            # models.UserGroup.objects.filter(id=2).delete()

            # 更新
            # models.UserGroup.objects.filter(id=2).update(title='公关部')


            group_list = models.UserGroup.objects.all()
            return render(request,'newindex.html',{"group_list": group_list})    
    # html
        <body>
            <ul>
                {% for row in group_list %}
                    <li>{{ row.id }} === {{ row.title }}</li>
                {% endfor %}
            </ul>
        </body>
        
        
    # 内容梳理    

        class Foo(models.Model):
            # nid = models.AutoField(primary_key=True) 自动创建
            name = models.CharField(max_length=32)
        class Bar(models.Model):
            title = ...
            f = FK...
            
        增加:
            Foo.objects.create(name='ff')
        获取:
            result = Foo.objects.all()
                QuerySet[Foo(),Foo()Foo()Foo()] --> 类似列表
            result = Foo.objects.filter(id=1)
                QuerySet[obj,]                  --> 列表
                QuerySet[obj,obj,obj]           --> 列表
            result = Foo.objects.filter(name="alex").first()
                obj                     .first()-->  对象
        删除:
            Foo.objects.filter(id=1).delete()
        更新:
            Foo.objects.filter(id=1).update()
    


    
            
- 连表操作

    # models.py
    
        # class Foo(models.Model):
        #     caption = models.CharField(max_length=16)
            
        class UserType(models.Model):
            """
            用户类型
            """
            title = models.CharField(max_length=32)
            # fo = models.ForeignKey('Foo')

        class UserInfo(models.Model):
            """
            用户表
            """
            name = models.CharField(max_length=16)
            age = models.IntegerField()
            ut = models.ForeignKey('UserType')
        
    # views.py
    
        # 创建数据:
        models.UserType.objects.create(title='普通用户')
        models.UserInfo.objects.create(name='方少伟',age=18,ut_id=1)
            
            
        # 获取多个数据
        # QuerySet[obj,obj,obj]
        # result = models.UserInfo.objects.all()
        # for obj in result:
        #       print(obj.name,obj.age,obj.ut_id,obj.ut.title)
        #      # print(obj.name,obj.age,obj.ut_id,obj.ut.fo.caption)
        
        
                        
        # 正向操作
        # UserInfo,ut是FK字段                
        # 一个用户只有一个用户类型
        
        # obj = models.UserInfo.objects.all().first()
        # print(obj.name,obj.age,obj.ut.title)

        
          
        # 反向操作
        # UserType, 表名小写_set.all()
        # 一个用户类型下可以有很多用户
        
        # obj = models.UserType.objects.all().first()
        # print(obj.id,obj.title)
        # #print(obj.id,obj.title,obj.userinfo_set.all())
        
        # for row in obj.userinfo_set.all():
        #       print(row.name,row.age)
            
    
            
        # 反向操作 二次筛选    
        # result = models.UserType.objects.all()
        # for item in result:
        #      # print(item.title,item.userinfo_set.all())
        #      print(item.title,item.userinfo_set.filter(name='xx'))
            
        # 只取 id,name
        # result = models.UserInfo.objects.all().values('id','name')
        # QuerySet[{'id':'xx','name':'xx'} ]     --> 里面是字典
        # for row in result:
        #       print(row)
            
        # 只取 id,name     
        # result = models.UserInfo.objects.all().values_list('id','name')
        # # QuerySet[(1,'f'), ]                  -->里面是元组
        # for row in result:
        #      print(row)

        
        # 后补充
        # models.UserInfo.objects.filter(id__gt=6).delete()

        # v=models.UserInfo.objects.values('id','name')
        # v=models.UserInfo.objects.values('id','name','ut__title')
        # # select * from userinfo left join usertype

        # v= models.UserType.objects.values('id','title')
        # print(v)
        # # v2= models.UserType.objects.values('id','title','userinfo')
        # select * from usertype left join userinfo
        # v2= models.UserType.objects.values('id','title','userinfo__name')
        # print(v2)
        
        
    # 获取多个数据时
    
        1. [obj,obj,obj,]
        
            models.UserInfo.objects.all()
            models.UserInfo.objects.filter(id__gt=1)
            result = models.UserInfo.objects.all()
            for item in result:
                print(item.name,item.ut.title)

        2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},]  
            里面是字典
        
            models.UserInfo.objects.all().values('id','name')
            models.UserInfo.objects.filter(id__gt=1).values('id','name')
            
            # 无法跨表
            result = models.UserInfo.objects.all().values('id','name')
            for item in result:
                print(item['id'],item['name'])
                
            # 夸表 __
            result = models.UserInfo.objects.all().values('id','name',"ut__title")
            for item in result:              # item是字典
                print(item['id'],item['name'],item['ut__title'])


        3. [(1,df),(2,'df')]   
            里面是元组
        
            models.UserInfo.objects.all().values_list('id','name')
            models.UserInfo.objects.filter(id__gt=1).values_list('id','name')
            
            # 无法跨表
            result = models.UserInfo.objects.all().values_list('id','name')
            for item in result:
                print(item[0],item[1])
                
            # 夸表  __
            result = models.UserInfo.objects.all().values_list('id','name',"ut__title")
            for item in result:              # item是元组
                print(item[0],item[1],item[2])
    # 内容梳理
    
        class UserGroup(models.Model):
            """
            部门 3
            """
            title = models.CharField(max_length=32)
        class UserInfo(models.Model):
            """
            员工4
            """
            nid = models.BigAutoField(primary_key=True)
            user = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
            age = models.IntegerField(default=1)
            # ug_id 1
            ug = models.ForeignKey("UserGroup",null=True)
            
        - 跨表
            正向操作:
                
                1. 对象方式  
                    q = UserInfo.objects.all().first()
                    q.ug.title
                    
                2. values
                    UserInfo.objects.values('nid','ug_id')              
                    UserInfo.objects.values('nid','ug_id','ug__title')  
                
                3. values_list
                    UserInfo.objects.values_list('nid','ug_id','ug__title')
                
            反向操作:
            
                1. 小写的表名_set    对象方式
                    obj = UserGroup.objects.all().first()
                    result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]
                   
                2. 小写的表名
                    v = UserGroup.objects.values('id','title')          
                    v = UserGroup.objects.values('id','title','小写的表名称')          
                    v = UserGroup.objects.values('id','title','小写的表名称__age')          
                    
                3. 小写的表名
                    v = UserGroup.objects.values_list('id','title')          
                    v = UserGroup.objects.values_list('id','title','小写的表名称')          
                    v = UserGroup.objects.values_list('id','title','小写的表名称__age')    

            PS: 前面的所有数据都会显示
            
        - 其他:
            UserInfo.objects.all()
            UserInfo.objects.filter(id=1,id=2)
            UserInfo.objects.all().first()
            UserInfo.objects.all().count()
            UserInfo.objects.all().update()
            UserInfo.objects.all().delete()
            UserInfo.objects.all()[1:19]
            
        - 跨表:
            正向:
                xxxx.filter(ut__title='超级用户').values('id','name','ut__title')
            反向:
                xxxx.filter(小写表名称__title='超级用户').values('id','name','小写表名称__title')
                
- ORM操作

    # 支持字典:
    
        class Foo:
            xx = in
        .
        1.增加
            create (name='xxx',age=18)
            
            dict={name:xxx,age:35}
            create(**dict)
            
        2.更新
            models.xx.objects.filter(id=1).update(a=1,b=2)
            models.xx.objects.filter(id=1).update(**dict)
        
        3.查询
            models.xx.objects.filter(id=1,xxx)
            models.xx.objects.filter(**{id:1,name='alex'})
            
        Form组件:
            数据转换成字典,用户请求规则验证


    1. 增删改查
    
    2. 一般:
        # models.UserInfo.objects.filter(id__gt=1)
        # models.UserInfo.objects.filter(id__lt=1)
        # models.UserInfo.objects.filter(id__lte=1)
        # models.UserInfo.objects.filter(id__gte=1)
        # models.UserInfo.objects.filter(id__in=[1,2,3])
        # models.UserInfo.objects.filter(id__range=[1,2])
        # models.UserInfo.objects.filter(name__startswith='xxxx')
        # models.UserInfo.objects.filter(name__contains='xxxx')
        # models.UserInfo.objects.exclude(id=1)    #id 不等于 1
        
    3. 排序
        user_list=models.UserInfo.objects.all().order_by('id')
        user_list=models.UserInfo.objects.all().order_by('-id')
        user_list=models.UserInfo.objects.all().order_by('-id','name')
        # id重复下,按照'name'排序
        
        """
        class UserInfo(models.Model):
            ...
            def __str__(self):
                return '%s-%s'%(self.id,self.name)
        """
    
    4. 分组
        from django.db.models import Count,Sum,Max,Min
        
        # v=models.UserInfo.objects.values('ut_id').annotate(xxx=Count('id'))
        # SELECT 'app01_userinfo'.'ut_id',COUNT('app01_userinfo'.'id') AS 'xxx'
            FROM 'app01_userinfo' GROUP BY 'app01_userinfo'.'ut_id'
        # print(v.query)  # 查看生成的语句

        # v=models.UserInfo.objects.values('ut_id').annotate(xxx=Count('id')).filter(xxx__gt=2)
        # having
        # + HAVING COUNT('app01_userinfo'.'id');
        # print(v.query)

        # v=models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxx=Count('id')).filter(xxx__gt=2)
        # where
        # SELECT 'app01_userinfo'.'ut_id',COUNT('app01_userinfo'.'id') AS 'xxx'
            FROM 'app01_userinfo' WHERE 'app01_userinfo'.'id' >2
            GROUP BY 'app01_userinfo'.'ut_id' HAVING COUNT('app01_userinfo'.'id');
        print(v.query)

        
        # models.UserInfo.objects.filter(id__gt=1)
        # models.UserInfo.objects.filter(id__lt=1)
        # models.UserInfo.objects.filter(id__lte=1)
        # models.UserInfo.objects.filter(id__gte=1)
        # models.UserInfo.objects.filter(id__in=[1,2,3])
        # models.UserInfo.objects.filter(id__range=[1,3])
        # models.UserInfo.objects.filter(name__startswith='xx')
        # models.UserInfo.objects.filter(name__contains='xx')
        # models.UserInfo.objects.exclude(id=1) # 不等于        
        # filter(age__isnull=True)
    
    5. F,更新时用于获取原来的值
        # from django.db.models import F,Q
        # models.UserInfo.objects.all().update(age=F("age")+1)
    
    6. Q,用于构造复杂查询条件
        # from django.db.models import F,Q
        
        # condition = {
        #     'id':1,
        #     'name': 'root'
        # }
        # models.UserInfo.objects.filter(**condition)
        # 条件写成字典型
    
        # 应用一:
        
            # models.UserInfo.objects.filter(Q(id__gt=1))
            # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))    # or 条件
            # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
            
        # 应用二:
        
            # q1 = Q()
            # q1.connector = 'OR'
            # q1.children.append(('id__gt', 1))
            # q1.children.append(('id', 10))
            # q1.children.append(('id', 9))
            #
            #
            # q2 = Q()
            # q2.connector = 'OR'
            # q2.children.append(('c1', 1))
            # q2.children.append(('c1', 10))
            # q2.children.append(('c1', 9))
            #
            # q3 = Q()
            # q3.connector = 'AND'
            # q3.children.append(('id', 1))
            # q3.children.append(('id', 2))
            # q2.add(q3,'OR')
            #
            # con = Q()
            # con.add(q1, 'AND')
            # con.add(q2, 'AND')
            
            # models.UserInfo.objects.filter(con)
                
        # 应用场景:组合搜索
        
            # condition_dict={
            #     'k1':[1,2,3,4],
            #     'k2':[1,],
            #     'k3':[11,]
            # }

            # con=Q()
            # for k,v in condition_dict:
            #     q=Q()
            #     q.connector='OR'
            #     for i in v:
            #         q.children.append('id',i)
            #     con.add(q,'AND')

            # models.UserInfo.objects.filter(con)
    
    7. extra, 额外查询条件以及相关表,排序

        例子:
            # """
            #     select
            #         id,
            #         name,
            #         (select count(1) from tb) as n
            #     from xb where ....
            # """

            
            
            # v = models.UserInfo.objects.all().extra(
            #     select={
            #         'n':"select count(1) from app01_usertype where id=%s or id=%s",
            #         'm':"select count(1) from app01_usertype where id=%s or id=%s",
            #     },
            #     select_params=[1,2,3,4])
            # for obj in v:
            #     print(obj.name,obj.id,obj.n)

            
            # models.UserInfo.objects.extra(
            #     where=["id=1","name='alex'"] # AND连接
            # )
            # models.UserInfo.objects.extra(
            #     where=["id=1 or id=%s ","name=%s"],
            #     params=[1,"alex"]
            # )

            # models.UserInfo.objects.extra(
            #     tables=['app01_usertype'],
            #      where={...}
            # )
            # """select * from app01_userinfo,app01_usertype"""    
            # select * from app01_usertype,app01_usertype WHERE app01_usertype.id= app01_userinfo.ut_id

    
        models.UserInfo.objects.filter(id__gt=1)
        models.UserInfo.objects.all()
        # id name age ut_id
    
    
        models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
        # a. 映射
            # select
            # select_params=None
            # select 此处 from 表
        
        # b. 条件
            # where=None
            # params=None,
            # select * from 表 where 此处
        
        # c. 表
            # tables
            # select * from 表,此处
            
        # d. 排序
            # order_by=None
            # select * from 表 order by 此处
        
        
        models.UserInfo.objects.extra(
            select={'newid':'select count(1) from app01_usertype where id>%s'},
            select_params=[1,],
            where = ['age>%s'],
            params=[18,],
            order_by=['-age'],
            tables=['app01_usertype']
        )
        """
        select
            app01_userinfo.id, # 隐含id
            (select count(1) from app01_usertype where id>1) as newid
        from app01_userinfo,app01_usertype
        where
            app01_userinfo.age > 18
        order by
            app01_userinfo.age desc
        """
        
        - 例子:
            # result = models.UserInfo.objects.filter(id__gt=1)
            # print(result.query)        
            
            result = models.UserInfo.objects.filter(id__gt=1).extra(
                where=['app01_userinfo.id < %s'],
                params=[100,],
                tables=['app01_usertype'],
                order_by=['-app01_userinfo.id'],
                select={'uid':1,'sw':"select count(1) from app01_userinfo"}
            )
            print(result.query)
            
            
            """
             SELECT
                (1) AS "uid", (select count(1) from app01_userinfo) AS "sw",
                "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id"
            FROM
                "app01_userinfo" , "app01_usertype"
            WHERE
                ("app01_userinfo"."id" > 1
            AND
                (app01_userinfo.id < 100))
            ORDER BY ("app01_userinfo".id) DESC
            """
            
            
    8. 原生SQL语句
    
        from django.db import connection, connections
        
        cursor = connection.cursor() # connection=default数据
        cursor = connections['db2'].cursor()
        
        cursor.execute("""SELECT * from auth_user where id = %s""", [1])
        
        row = cursor.fetchone()
        row = cursor.fetchall()
        
        
        - extra
        - 原生SQL语句
        - raw
            result = models.UserInfo.objects.raw('select * from userinfo')
            [obj(UserInfo),obj,]
            result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')
            [obj(UserInfo),obj,]
            
    
    9. 简单的操作
        博客地址:www.cnblogs.com/wupeiqi/articles/6216618.html  
        其他操作,除去 select_related \ prefetch_related
    
        a. distinct补充:
            数据源:
            mysql/sqlite distinct里面不传参数
                    models.UserInfo.object.values('nid').distinct()
                    # select distinct nid from userinfo
            PostgreSQL:
                    models.UserInfo.object.distinct('nid')
                    # select distinct nid from userinfo
    
        b. reverse() 必须在使用 order_by 之后
            # v = models.UserInfo.objects.all().order_by('-id','name')
            # v = models.UserInfo.objects.all().order_by('-id','name').reverse()
            # v = models.UserInfo.objects.all().order_by('id','-name')
            # print(v)

        c. only/defer
            # v = models.UserInfo.objects.all()
            # [obj]

            # v = models.UserInfo.objects.all().only('id','name')  # 内部元素还是对象
            # v = models.UserInfo.objects.all().defer('name')      # 除了name所有值
            # # [obj]
            # for obj in v:
            #     obj.id,obj.name
        
        d. using
            # models.UserInfo.objects.all().using('db2')
        
        # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET
        # 以上方法可以一直.操作
        
        values
        value_list            
        dates
        datetimes
        none
        
        aggregate
            # 整张表聚合
            # models.UserInfo.objects.none()
            # result = models.UserInfo.objects.aggregate(k=Count('ut_id', distinct=True), n=Count('id'))
            # print(result)    #字典
            
        count
        
        get
            # 找到一个正确,其他报错
            # v = models.UserInfo.objects.all().first()
            # # models.UserInfo.objects.get(id=1)    
            
        creat
            # obj = models.UserType.objects.create(title='xxx')
            # obj = models.UserType.objects.create(**{'title': 'xxx'})
            # print(obj.id) #lastrowid 获取自增id
        
        save
            # obj = models.UserType(title='xxx')
            # obj.save()
            
        bulk_create
            # objs = [
            #     models.UserInfo(name='r11'),
            #     models.UserInfo(name='r11'),
            #     models.UserInfo(name='r11'),
            # ]
            # models.UserInfo.objects.bulk_create(objs, 10) # 不超多999
            
        get_or_create
        update_or_create            
            # obj, created = models.UserInfo.objects.get_or_create(
            #     username='root1',
            #     pwd='ff',
            #     defaults={'email': '1111111','u_id': 2, 't_id': 2})
            
        in_bulk
            # models.UserInfo.objects.filter(id__in=[1,2,3])
            # models.UserInfo.objects.in_bulk([1,2,3])    # 主键
        
        raw
            # name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
            # models.UserInfo.objects.raw('SELECT * FROM app01_usertype', translations=name_map)
            name_map = {'title': 'name'}
            v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)
            for i in v1:
                print(i,type(i))
                
    10. 补充
    
        # 造成多次查询
        # q = models.UserInfo.objects.all()
        # for row in q:
        #     print(row.name,row.ut.title)
        
        
        # select_related: 查询主动做连表
        # q = models.UserInfo.objects.all().select_related('ut','gp')
        # select * from userinfo
        # select * from userinfo inner join usertype on ...
        # for row in q:
        #     print(row.name,row.ut.title)

        
        # prefetch_related: 不做连表,做多次查询
        # q = models.UserInfo.objects.all().prefetch_related('ut')        
        # 做两次查询
        # select * from userinfo;
        # Django内部:ut_id = [2,4]
        # select * from usertype where id in [2,4]
        # for row in q:
        #     print(row.id,row.ut.title)
        
        
- 多对多操作

    - 自定义关系表
    
        class Boy(models.Model):
            name = models.CharField(max_length=32)


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

        class Love(models.Model):
            b = models.ForeignKey('Boy')
            g = models.ForeignKey('Girl')
        #     class Meta:
        #         unique_together =[
        #             ('b','g'),
        #         ]
        # 联合唯一
            
            
        # 数据初始化
        # objs=[
        #     models.Boy(name='fangshaowei'),
        #     models.Boy(name='youqinbing'),
        #     models.Boy(name='chentao'),
        #     models.Boy(name='yanlong'),
        #     models.Boy(name='wuyanzu'),
        # ]
        # models.Boy.objects.bulk_create(objs,5)

        # objss=[
        #     models.Girl(nick='xiaoyu'),
        #     models.Girl(nick='xiaozhou'),
        #     models.Girl(nick='xiaomao'),
        #     models.Girl(nick='xiaogou'),
        # ]
        # models.Girl.objects.bulk_create(objss,5)

        # models.Love.objects.create(b_id=1,g_id=1)
        # models.Love.objects.create(b_id=1,g_id=4)
        # models.Love.objects.create(b_id=2,g_id=4)
        # models.Love.objects.create(b_id=2,g_id=2)            
            
            
            
        # 和方少伟有关系的姑娘
        # obj = models.Boy.objects.filter(name='方少伟').first()
        # love_list = obj.love_set.all()
        # for row in love_list:
        #     print(row.g.nick)

        # love_list = models.Love.objects.filter(b__name='方少伟')
        # for row in love_list:
        #     print(row.g.nick)

        # 优化查询1:
        # love_list = models.Love.objects.filter(b__name='方少伟').values('g__nick')
        # for item in love_list:
        #     print(item['g__nick'])
        
        # 优化查询2:
        # love_list = models.Love.objects.filter(b__name='方少伟').select_related('g')
        # for obj in love_list:
        #     print(obj.g.nick)

    - ManyToManyField
    
    
        class Boy(models.Model):
            name=models.CharField(max_length=32)
            m = models.ManyToManyField('Girl')
            
        # 生成 app01_boy_m 表
        # id boy_id girl_id

        class Girl(models.Model):
            nick=models.CharField(max_length=32)
            # m = models.ManyToManyField('Boy')

            
            
        # obj = models.Boy.objects.filter(name='fangshaowei').first()
        # print(obj.id,obj.name)
        # 增加:
        # obj.m.add(3)      # 增加数据:1,1,3
        # obj.m.add(2,4)    # 1,2;1,4
        # obj.m.add(*[1,])

        # 删除
        # obj.m.remove(1)
        # obj.m.remove(2,3)
        # obj.m.remove(*[4,])

        # 重置
        # obj.m.set([1,])     #重置

        # 获取
        # q=obj.m.all()
        # [girl 对象]
        # print(q)
        # obj = models.Boy.objects.filter(name='fangshaowei').first()
        # girl_list =obj.m.all()

        # 获取后继续筛选
        # obj = models.Boy.objects.filter(name='fangshaowei').first()
        # # girl_list =obj.m.all()
        # girl_list=obj.m.filter(nick='xiaoyu') # 继续筛选
        # print(girl_list)

        # 删除
        # obj = models.Boy.objects.filter(name='fangshaowei').first()
        # obj.m.clear()


        
        # 从无ManyToMany字段的表查询:反向,其他操作方法一致。
        # obj=models.Girl.objects.filter(nick='xiaoyu').first()
        # print(obj.id,obj.nick)
        # v = obj.boy_set.all()
        # print(v)

        
    - 两者结合

        class Boy(models.Model):
            name=models.CharField(max_length=32)
            m = models.ManyToManyField('Girl',through='Love',through_fields=('b','g',))
            # 提供查询和清空 clear()

        class Girl(models.Model):
            nick=models.CharField(max_length=32)
            # m = models.ManyToManyField('Boy')

        class Love(models.Model):
            b = models.ForeignKey('Boy')
            g = models.ForeignKey('Girl')

            class Meta:
                unique_together =[
                    ('b','g'),
                ]

        obj = models.Boy.objects.filter(name='方少伟').first()
        # obj.m.add(1) 错误
        # obj.m.remove(1) 错误
        # obj.m.clear() 可以
        v = obj.m.all()
        print(v)

        
- 操作总结:

    - 增删改查
    - filter(),update(),create()  可以使用字典:**
    - all()  values()   values_list()
    - FK
        正向:
            filter() values,values_list() -> 跨表  fk__xxx
            objs = all()
            for obj in objs:
                obj.fk.
        反向:
            filter() values,values_list() -> 跨表  小写表名称__xxx
            objs = all()
            for obj in objs:
                obj.表名称_set.all()
    - M2M:
        - M2M
        - 自定义
        - M2M+自定义
                
        正向(有M2M):
            obj = ...
            obj.m.add()
            obj.m.remove()
            obj.m.set()
            obj.m.clear()
            obj.m.all()...
        反向:
            obj ...
            obj.表名_set.add
            ...
            
        M2M+自定义
            obj.m.clear()
            obj.m.all()...

- 相亲网示例1(多对多表单独):

    # urls.py
    
        from django.conf.urls import url
        from django.contrib import admin
        from app01.views import account
        from app01.views import love


        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            url(r'^login.html$', account.login),
            url(r'^logout.html$', account.logout),

            url(r'^index.html$', love.index),
            url(r'^others.html$', love.others),
        ]

    # models.py

        from django.db import models

        # Create your models here.
        class Boy(models.Model):
            nickname = models.CharField(max_length=32)
            username = models.CharField(max_length=32)
            password =models.CharField(max_length=64)

        class Girl(models.Model):
            nickname = models.CharField(max_length=32)
            username = models.CharField(max_length=32)
            password = models.CharField(max_length=64)

        class B2G(models.Model):
            b = models.ForeignKey(to='Boy',to_field='id')
            g = models.ForeignKey(to='Girl',to_field='id')
        
    # views/account.py

        from django.shortcuts import render,HttpResponse,redirect
        from app01 import models
        def login(request):
            if request.method =="GET":
                return render(request,'login.html')
            else:
                user=request.POST.get('username')
                pwd=request.POST.get('password')
                gender=request.POST.get('gender')
                rmb=request.POST.get('rmb')
                #性别判断:
                if gender == '1':
                    obj=models.Boy.objects.filter(username=user,password=pwd).first()
                else:
                    obj=models.Girl.objects.filter(username=user,password=pwd).first()
                if not obj:
                    #未登陆成功
                    return render(request,'login.html',{'msg':'用户名或密码错误'})
                else:
                    # request.session['user_id']=obj.id
                    # request.session['gender']=gender
                    # request.session['username']=user
                    request.session['user_info']={'user_id':obj.id,'gender':gender,'username':user,'nickname':obj.nickname}
                    return redirect('/index.html')

        def logout(request):
            if request.session.get('user_info'):

                request.session.clear()
                # request.session.delete(request.session.session_key)
            return redirect('/login.html')

            
    # views/love.py

        from django.shortcuts import render,HttpResponse,redirect
        from app01 import models
        def index(request):
            if  not request.session.get('user_info'):
                return redirect('/login.html')
            else:
                #男:女生列表
                #女:男生
                gender =request.session.get('user_info').get('gender')
                if gender == '1':
                    user_list=models.Girl.objects.all()
                else:
                    user_list=models.Boy.objects.all()
                return render(request,'index.html',{'user_list':user_list})


        def others(request):
            #获取与当前用户有关系的异性
            current_user_id=request.session.get('user_info').get('user_id')
            gender = request.session.get('user_info').get('gender')
            if gender =='1':
                user_list=models.B2G.objects.filter(b_id=current_user_id).values('g__nickname')
            else:
                user_list=models.B2G.objects.filter(g_id=current_user_id).values('b__nickname')
            return render(request,'others.html',{'user_list':user_list})

            
    # login.html

        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <form method="POST" action="/login.html">
                {% csrf_token %}
                <p>用户:<input type="text" name="username"></p>
                <p>密码:<input type="password" name="password"></p>
                <p>
                    性别:
                    男 <input type="radio"name="gender" value="1">
                    女 <input type="radio"name="gender" value="2">
                </p>
                <p><input type="checkbox" name="rmb"value="11">一个月免登陆</p>
                    <input type="submit"value="提交">{{ msg }}
            </form>
        </body>
        </html>
        
        
    # index.html
    
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            {% include 'user_header.html' %}

            <h2>异性列表</h2>
            <a href="/others.html">查看和我有关系的异性</a>
            <ul>
                {% for row in user_list %}
                    <li>{{ row.nickname }}</li>
                {% endfor %}
            </ul>
        </body>
        </html>
        
    # others.py
    
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>

            {% include 'user_header.html' %}
            <h1>有关系的异性列表</h1>
            <ul>
            {% for row in user_list %}
                {% if row.g__nickname %}
                    <li>{{ row.g__nickname }}</li>
                {% else %}
                    <li>{{ row.b__nickname }}</li>
                {% endif %}
            {% endfor %}
            </ul>
        </body>
        </html>
    
    # templates/user_header.html
    
        <h1>当前用户:{{ request.session.user_info.nickname }}</h1>
        <a href="/logout.html">注销</a>    

        
        
- 相亲网示例2(多对多两张表):

    # models.py
    
        class UserInfo(models.Model):
            nickname = models.CharField(max_length=32)
            username = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
            gender_choices = (
                (1,'男'),
                (2,'女'),
            )
            gender = models.IntegerField(choices=gender_choices)

        class U2U(models.Model):
            g = models.ForeignKey('UserInfo',related_name='boys')
            b = models.ForeignKey('UserInfo',related_name='girls')
            
            
        # 反向查找时 obj对象:u2u_set.all()无法区分,必须添加related_name
        
        # related_query_name
        # obj对象男.b_set.all()
        # obj对象女.a_set.all()
        
        # related_name
        # obj对象男.a.all()
        # obj对象女.b.all()
        
        # U2U.objects.create(g_id=a1,b_id=a2)
        # 自行判断插入数据
        
        
        # related_query_name,related_name示例
        
        # class UserType(models.Model):
        #     title = models.CharField(max_length=32)
        #
        # class User(models.Model):
        #     username = models.CharField(max_length=32)
        #     ut = models.ForeignKey('UserType',related_query_name='xxxx') users

        # 反向:
        # related_name='xxxx'
        #   user_set ==> xxxx
        # related_query_name='xxxx'
        #   user_set ==> xxxx_set   obj.users

        
- 相亲网示例2(多对多自关联):


    # models.py
    
        class UserInfo(models.Model):
            nickname = models.CharField(max_length=32)
            username = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
            gender_choices = (
                (1,'男'),
                (2,'女'),
            )
            gender = models.IntegerField(choices=gender_choices)

            m = models.ManyToManyField('UserInfo')
            # app01_userinfo_m
            # id,from_userinfo_id,to_userinfo_id
            
    # views.py
    
        # 查男生
        # xz = models.UserInfo.objects.filter(id=1).first()
        # u = xz.m.all()
        # for row in u:
        #     print(row.nickname)
        
        # 查女神
        # xz = models.UserInfo.objects.filter(id=4).first()
        # v = xz.userinfo_set.all()
        # for row in v:
        #     print(row.nickname)    
        

    - 梳理;
        M2M自关联特性:
            obj = models.UserInfo.objects.filter(id=1).first()
            # from_userinfo_id
            obj.m            => select xx from xx where from_userinfo_id = 1
            
            # to_userinfo_id
            obj.userinfo_set => select xx from xx where to_userinfo_id = 1
            
        
        定义:
            # 前面列:男生ID
            # 后面列:女生ID
            
        应用:
            # 男生对象
            obj = models.UserInfo.objects.filter(id=1).first()
            # 根据男生ID=1查找关联的所有的女神
            obj.m.all()
            
            # 女生
            obj = models.UserInfo.objects.filter(id=4).first()
            # 根据女生ID=4查找关联的所有的男生
            obj.userinfo_set.all()    
            
            

- 评论表示例(Fk自关联):

    # models.py FK自关联

        class Comment(models.Model):
            """
            评论表
            """
            news_id = models.IntegerField()            # 新闻ID
            content = models.CharField(max_length=32)  # 评论内容
            user = models.CharField(max_length=32)     # 评论者
            reply = models.ForeignKey('Comment',null=True,blank=True,related_name='xxxx')

        """
           新闻ID                         reply_id
        1   1        别比比    root         null
        2   1        就比比    root         null
        3   1        瞎比比    shaowei      null
        4   2        写的正好  root         null
        5   1        拉倒吧    yqb            2
        6   1        拉倒吧1    xxxxx         2
        7   1        拉倒吧2    xxxxx         5
        """


posted @ 2020-01-18 21:03  badweather  阅读(76)  评论(0编辑  收藏  举报