s14_06_Model_基础

model操作基础

        
- Model

    # django为使用一种新的方式,
    # 即:关系对象映射(Object Relational Mapping,简称ORM)。

    # django中遵循 Code Frist 的原则,
    # 即:根据代码中定义的类来自动生成数据库表。
    # db first & code first
    
    # 根据类自动创建数据库表
    # 根据类对数据库表中的数据进行各种操作

    
- 基本操作
            
    a. 先写类
    
        # app下的models.py
        from django.db import models

        # app01_userinfo
        class UserInfo(models.Model):
            # 隐含id列,自增,主键
            # 用户名列,字符串类型,指定长度
            username = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
        
    b. 注册APP

        INSTALLED_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'app01',
        ]
        
    c. 执行命令
        
        # 先注册app
        根据类自动创建数据库表
        python manage.py  makemigrations
        python manage.py  migrate

        
    d. 其他
    
        - Django默认使用MySQLdb模块链接MySQL
        - 修改为pymysql,在project同名文件夹下__init__文件添加代码:
            
            import pymysql
            pymysql.install_as_MySQLdb()
            
        - 根据数据库,配置参数:
        
            mysql配置如下:
            
            DATABASES = {
                'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME':'dbname',    # 手动创建数据库
                'USER': 'root',
                'PASSWORD': 'xxx',
                'HOST': '',
                'PORT': '',
                }
            }
    
        - pycharm数据库驱动
            C:\Users\jacka\.PyCharm2019.2\config\jdbc-drivers
            
        - 使用navicat链接sqlite
            - 右击复制copy path
            - nivacat:新建连接- 数据库文件

        - views.py
            from app01 import models
            
        - admin.py
        
            from django.contrib import admin
            from app01 import models
            # Register your models here.
            admin.site.register(models.UserInfo)
            
            创建 Django 用户:python manage.py createsuperuser            
                   
           
# 一对多/一对一/多对多
    
    一对一:
            外键唯一约束。
    
    一对多:
            def func():
                    
                return 5
            
            
            class UserType(models.Model):
                name = models.CharField(max_length=32)
                
            
            class User(models.Model):
                name = models.CharField(max_length=32)
                pwd = models.CharField(max_length=32)
                ForiegnKey(to="UserType",to_field='id',on_delete=models.SET(func))
            
            # delete from user where id=1
            # delete from UserType where id=1 # 报错
            
            # UserType.objects.filter(id=1).delete()
            # 新版本关联数据默认都删除
        
        
            
            # 正向查找
            # v = User.objects.all()
            # for item in v:
            #     item.user
            #     item.pwd
            #     item.ut.name

            # User.objects.all().values('user','ut__name')


            # 反向查找
            # v= UserType.objects.all()
            # for item in v:
            #     item.name
            #     item.id
            #     item.user_set.all()
            # related_name='b' ==> item.b.all()
            # related_query_name='a' ==>  item.a_set.all()

            # UserType.objects.all().values('name','user__pwd')
            
    - 多对多:
        a. django创建第三张表
            m2m.remove
            m2m.add
            m2m.set
            m2m.clear
            m2m.filter()
        b. 自定义第三张表(无m2m字段)
            
            自己链表查询
            
        c. 自定义第三张表(有m2m字段)
            # 通过m2m字段查操作
            # 通过m2m字段 clear        
        

- QuerySet中的方法:

    - 返回QuerySet类型(select_related,prefetch_related)
        
        select_related
        
            users = models.User.objects.all().select_related('ut')
            for row in users:
                print(row.user,row.pwd,row.ut_id)
                print(row.ut.name)
                print(row.tu.name) # 再发起一次SQL请求
        
        prefetch_related
            
            users = models.User.objects.filter(id__gt=30).prefetch_related('ut','tu')
            # select * from users where id > 30
            # 获取上一步骤中所有的ut_id=[1,2]
            # select * from user_type where id in [1,2]
            # select * from user_type where id in [1,2]
            
            for row in users:
                print(row.user,row.pwd,row.ut_id)
                print(row.ut.name)
                
- 数据验证(弱)
    
    full_clean进行验证
        - 每个字段的正则
        - clean钩子

        class UserInfo(models.Model):
            name=models.CharField(max_length=32)
            email = models.EmailField()
            # 预留的方法
            def clean(self):
                from django.core.exceptions import ValidationError
                c = UserInfo.objects.filter(name=self.name).count()
                if c:
                    # 主动报错
                    raise ValidationError(message='用户名已经存在',code='i1')               
        
- 操作表    
    

    - 增
        models.User.objects.create(name='qianxiaohu',age=18)
        dic = {'name': 'xx', 'age': 19}
        models.User.objects.create(**dic)
        
        obj = models.User(name='qianxiaohu',age=18)    # 也可以传字典
        obj.save()
        
    - 删
        models.User.objects.filter(id=1).delete()
        
    - 改
        models.User.objects.filter(id__gt=1).update(name='alex',age=84)
        dic = {'name': 'xx', 'age': 19}
        models.User.objects.filter(id__gt=1).update(**dic)
        
    - 查
    
        models.User.objects.all()
        models.User.objects.filter(id=1,name='root')
        models.User.objects.filter(id__gt=1,name='root')
        models.User.objects.filter(id__lt=1)
        models.User.objects.filter(id__gte=1)
        models.User.objects.filter(id__lte=1)
        
        models.User.objects.filter(id=1,name='root')
        dic = {'name': 'xx', 'age__gt': 19}
        models.User.objects.filter(**dic)

        
    - 查2
    
        v1 = models.Business.objects.all()
        # QuerySet ,内部元素都是对象
                
        v2 = models.Business.objects.all().values('id','caption')
        # QuerySet ,内部元素都是字典
        
        v3 = models.Business.objects.all().values_list('id','caption')
        # QuerySet ,内部元素都是元组
        
        
        models.Business.objects.get(id=1)
        # 获取到的一个对象,如果不存在就报错
        
        models.Business.objects.filter(id=1).first()
        # 对象或者None
        
    外键:
    
        v = models.Host.objects.filter(nid__gt=0)
        v[0].b.caption  ---->  通过.进行跨表
        
        v1 = models.Host.objects.filter(nid__gt=0)
        # for row in v1:
        #     print(row.nid,row.hostname,row.ip,row.port,row.b_id,row.b.caption,row.b.code,row.b.id,sep='\t')

        v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','b_id','b__caption')
        # models.Host.objects.后面跨表用双下划线: "__" ,为普通字符串,取值时为对象
        # print(v2)
        # QuerySet[{内部为字典},{字典}]
        # for row in v2:
        #     print(row['nid'],row['hostname'],row['b_id'],row['b__caption'])

        v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','b_id','b__caption')

    
        class UserType(models.Model):
            caption = models.CharField(max_length=32)    
        # id  caption
            
        class User(models.Model):
            age = models.IntergerFiled()
            name = models.CharField(max_length=10)#字符长度
            # user_type_id = models.IntergerFiled() # 约束
            user_type = models.ForeignKey("UserType",to_field='id') # 约束
        # name  age  user_type_id    
        

        # models.tb.object.create(name='root', user_group_id=1)    
        # userlist = models.tb.object.all()
            for row in userlist:
                row.id
                row.user_group_id
                row.user_group.caption
                
        # user = User.objects.get(id=1)    # 得到单个对象
                

    - 序号相关
    
        {% for row in v1 %}
            <td>{{ forloop.counter}}</td>        # 序号从1开始
            <td>{{ forloop.counter0}}</td>        # 序号从0开始
            <td>{{ forloop.revcounter}}</td>    # 倒序从1开始
            <td>{{ forloop.revcounter0}}</td>    # 倒序从0开始
            <td>{{ forloop.last}}</td>            # 是否最后一个
            <td>{{ forloop.firs}}</td>            # 是否第一个
            <td>{{ forloop.parentloop}}</td>    # 如嵌套,显示父循环次数
        {%endfor%}



- 多对多:

    - 自定义关系表
    
        class Host(models.Model):
            nid = models.AutoField(primary_key=True)
            hostname = models.CharField(max_length=32,db_index=True)
            ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
            port = models.IntegerField()
            b = models.ForeignKey(to="Business", to_field='id')

        class Application(models.Model):
            name = models.CharField(max_length=32)
        
        class HostToApp(models.Model):
            hobj = models.ForeignKey(to='Host',to_field='nid')
            aobj = models.ForeignKey(to='Application',to_field='id')
            
        # app01_hosttoapp 表 id,aobj_id,hobj_id    
        # HostToApp.objects.create(hobj_id=1,aobj_id=2)
            
        
            
    - 自动创建关系表
    
        class Host(models.Model):
            nid = models.AutoField(primary_key=True)
            hostname = models.CharField(max_length=32,db_index=True)
            ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
            port = models.IntegerField()
            b = models.ForeignKey(to="Business", to_field='id')
        
        class Application(models.Model):
            name = models.CharField(max_length=32)
            r = models.ManyToManyField("Host")
        
        # app01.application_r 表 id,application_id,host_id    
        # 无法直接对第三张表进行操作
        
        
        obj = Application.objects.get(id=1)
        obj.name
        
    - 第三张表操作
    
        obj.r.add(1)
        obj.r.add(2)
        obj.r.add(2,3,4)
        obj.r.add(*[1,2,3,4])
        
        obj.r.remove(1)
        obj.r.remove(2,4)
        obj.r.remove(*[1,2,3])
        
        obj.r.clear()
        
        obj.r.set([3,5,7])
        
        # objects后的都可以使用
        obj.r.all()
        
        # 所有相关的主机对象“列表” QuerySet
        obj.r.all()            



 

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