zoukankan      html  css  js  c++  java
  • 3.django Model

    django ORM基本配置

    django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表

    1.修改project数据库配置

    (1)settigs.py里面

    默认

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

     修改为mysql数据库:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'mysql',        #数据库名字
            'USER': 'root',          #账号
            'PASSWORD': '123456',      #密码
            'HOST': '192.168.43.128',    #IP
            'PORT': '3306',                   #端口
        }
    }

    (2)把模块改成pymysql

    修改project目录下的init.py

    import  pymysql
    pymysql.install_as_MySQLdb()

    2.创建数据库表结构文件

    对应app目录下的models.py

    (1)生成一个简单的数据库表:

    from django.db import models
    
    class UseInfo(models.Model):
        username = models.CharField(max_length=32)
        passwd = models.CharField(max_length=64)
    
    # 数据库默认创建id列 自增 主键
    # 用户名列 字符串类型 字符长度

    (2)把app名称加入到settings里面

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'cmdb',          # 系统会加载cmdb下的model.py文件
    ] 

    (3)执行命令生成到数据库

    python manage.py  makemigrations
    python manage.py  migrate         # 生成数据表

    3.数据库字段和字段参数

    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
      继承CharField,所以必须 max_lenght 参数
    5、models.DateField  日期类型 date
      对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
    6、models.DateTimeField  日期类型 datetime
      同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正则表达式)不再使用
    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   图片
    24、models.FilePathField 文件
    
    所有字段...
    字段
    null               -> db是否可以为空
    default            -> 默认值
    primary_key        -> 主键
    db_column          -> 列名
    db_index           -> 索引
    unique               -> 唯一索引
    unique_for_date    ->
    unique_for_month
    unique_for_year
    auto_now            -> 更新时,自动更新为当前时间
    auto_now_add        -> 创建时,自动生成时间
    choices              -> django admin中显示下拉框,避免连表查询
    blank             -> django admin是否可以为空
    verbose_name      -> django admin显示字段中文
    editable          -> django admin是否可以被编辑
    error_messages    -> 错误信息欠
    help_text         -> django admin提示
    validators          -> django
    form, 自定义错误信息(欠)
    
    所有字段参数...
    字段参数

     数据库基本操作

     1.增加数据

     (1)最常用的方式

    from cmdb import models
    
    def userinfo(request):
        models.UseInfo.objects.create(username='derek',passwd='666')
        return HttpResponse('这种最常用')

    (2)第二种跟第一种差不多

    def userinfo(request):
        # models.UseInfo.objects.create(username='derek',passwd='666')
        # return HttpResponse('这种最常用')
        dicts = {'username':'jack','passwd':'999'}
        models.UseInfo.objects.create(**dicts)
        return HttpResponse('第二种跟第一种差不多')

    (3)第三种

    def userinfo(request):
        obj = models.UseInfo(username='tom',passwd='333')
        obj.save()
        return HttpResponse('第三种')

    2.查询数据

    (1)查询所有

    def select(request):
        result = models.UseInfo.objects.all()
        print(result)   #QuerySetL类型 
        for row in result:
            print(row.id,row.username,row.passwd)
        return HttpResponse('select')

    (2)查询指定字段

    def select(request):
        result = models.UseInfo.objects.filter(username='derek')
        if result:
            for row in result:
                print(row.id,row.username,row.passwd)
        return HttpResponse('select')

    3.删除数据

    def select(request):
        models.UseInfo.objects.filter(id=3).delete()
        return HttpResponse('select')

    4.更新数据

    def select(request):
        models.UseInfo.objects.filter(id=2).update(passwd='8888')
        return HttpResponse('select')

     数据库一对多操作

    1.数据表结构

    from django.db import models
    
    class UseGroup(models.Model):
        uid = models.AutoField(primary_key=True)   #主键,自增
        caption = models.CharField(max_length=32,unique=True)   #唯一索引
        ctime = models.DateField(auto_now_add=True,null=True)   #创建时生成时间
        uptime = models.DateField(auto_now=True,null=True)      #更新时自动更新时间
    
    class UseInfo(models.Model):
        username = models.CharField(max_length=32)
        passwd = models.CharField(max_length=64)
        # 关联外键,生成字段名为user_group_id
        user_group = models.ForeignKey("UseGroup",to_field="uid",default=1)

    2.外键关联添加数据

    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    def add(request):
        ug_obj = models.UseGroup.objects.create(caption = "外键数据添加")
        # 把外键ug_obj当参数传入
        models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj)
        return HttpResponse('11')

    3.外键关联表操作

    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # def add(request):
    #     ug_obj = models.UseGroup.objects.create(caption = "外键数据添加")
    #     # 把外键ug_obj当参数传入
    #     models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj)
    #     return HttpResponse('11')
    
    def ormadd(request):
        models.UseInfo.objects.create(username='jack',passwd='456')
        return HttpResponse('22')
    
    def ormgroup(request):
        models.UseGroup.objects.create(caption='CEO')
        return HttpResponse('33')
    
    def userinfo(request):
        obj = models.UseInfo.objects.all().first()
        print(obj.id,obj.username,obj.user_group_id)
        print(obj.user_group.uid,obj.user_group.caption)
        return HttpResponse('44')

    返回结果:

     4.跨表查询使用双下划綫 "__"

    from django.db import models
    
    class Business(models.Model):
        caption = models.CharField(max_length=32)
        code = models.CharField(max_length=32,null=True,default='QA')
    
    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')

    获取表单数据

    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    def home(request):
        v2 = models.Host.objects.filter(nid=1).values('nid','hostname','b_id','b__caption')
        print(v2)
        return HttpResponse('33')

    <QuerySet [{'nid': 1, 'hostname': 'c1.com', 'b_id': 1, 'b__caption': '运维'}]>

     实例(一) 模板中显示数据库内容的方法

     创建数据库

    from django.db import models
    from django.db import models
    
    class Business(models.Model):
        caption = models.CharField(max_length=32)
        code = models.CharField(max_length=32)
    
    class Host(models.Model):
        nid = models.AutoField(primary_key=True)
        hostname = models.CharField(max_length=32,db_index=True)
        ip = models.GenericIPAddressField(protocol='both',db_index=True)
        port = models.IntegerField()
        business = models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>业务线列表(对象)</h1>
        <ul>
            {% for row in v1 %}
                <li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li>
            {% endfor %}
        </ul>
    
        <h1>业务线列表(字典)</h1>
        <ul>
            {% for row2 in v2 %}
                <li>{{ row2.id }}-{{ row2.caption }}</li>
            {% endfor %}
        </ul>
    
    
    
    </body>
    </html>
    business.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>主机列表(对象)</h1>
        <table border="1">
            <tread>
                <tr>
                    <th>主机ID</th>
                    <th>IP</th>
                    <th>端口</th>
                    <th>业务线名称</th>
                </tr>
            </tread>
            <tbody>
                {% for row in v1 %}
                    <tr>
                        <td>{{ row.hostname }}</td>
                        <td>{{ row.ip }}</td>
                        <td>{{ row.port }}</td>
                        <td>{{ row.business.caption }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    
        <h1>主机列表(字典)</h1>
        <table border="1">
            <tread>
                <tr>
                    <th>主机ID</th>
                    <th>主机名</th>
                    <th>业务线ID</th>
                    <th>业务线名称</th>
                </tr>
            </tread>
            <tbody>
                {% for row in v2 %}
                    <tr>
                        <td>{{ row.nid }}</td>
                        <td>{{ row.hostname }}</td>
                        <td>{{ row.business__id }}</td>
                        <td>{{ row.business__caption }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    
        <h1>主机列表(元祖)</h1>
        <table border="1">
            <tread>
                <tr>
                    <th>主机ID</th>
                    <th>主机名</th>
                    <th>业务线ID</th>
                    <th>业务线名称</th>
                </tr>
            </tread>
            <tbody>
                {% for row in v3 %}
                    <tr>
                        <td>{{ row.0 }}</td>
                        <td>{{ row.1 }}</td>
                        <td>{{ row.2 }}</td>
                        <td>{{ row.3 }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    </body>
    </html>
    host.html
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    def business(request):
        # 第一种方式(是个对象)
        v1 = models.Business.objects.all()
        # 第二种方式,只取id和caption(是个字典)
        v2 = models.Business.objects.all().values('id','caption')
        return render(request,'business.html',{'v1':v1,'v2':v2})
    
    def host(request):
        #总共三种方式,对象,字典,列表
        v1 = models.Host.objects.all()
        v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','business__id','business__caption')
        v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','business__id','business__caption')
        return render(request,'host.html',{'v1':v1,'v2':v2,'v3':v3})

     实例(二)  一对多

     1.创建

    from django.db import models
    
    class UserType(models.Model):
        title = models.CharField(max_length=32)
    
    class UserInfo(models.Model):
        name = models.CharField(max_length=16)
        age = models.IntegerField()
        ut = models.ForeignKey('UserType')
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    def add(request):
        models.UserType.objects.create(title='普通用户')
        models.UserType.objects.create(title='黄金用户')
        models.UserType.objects.create(title='白金用户')
    
        models.UserInfo.objects.create(name='aa', age=18, ut_id=1)
        models.UserInfo.objects.create(name='bb', age=18, ut_id=2)
        models.UserInfo.objects.create(name='cc', age=18, ut_id=2)
        return HttpResponse('ok')

    2.操作

    (1)查询所有用户和类型

    def op(request):
        obj = models.UserInfo.objects.all()
        for row in obj:
            print(row.name,row.age,row.ut.title)
        return HttpResponse('ok')
    
    #查看所有
    aa 18 普通用户
    bb 18 黄金用户
    cc 18 黄金用户
    
    #查看第一条
    obj = models.UserInfo.objects.all().first()
    print(obj.name, obj.age, obj.ut.title)
    
    aa 18 普通用户

     (2)查询所有类型为“黄金用户的”用户

    正向查

    #这里跨表查询要用到双下划线"__"
    result = models.UserInfo.objects.filter(ut__title='黄金用户') for item in result: print(item.name,item.age,item.ut.title) 结果: bb 18 黄金用户 cc 18 黄金用户

    反向查

    obj = models.UserType.objects.get(id=2)
        result = obj.userinfo_set.all()
        #这里的userinfo_set相当于models.UserInfo.objects.filter(ut="黄金用户")
        for item in result:
            print(item.name,item.age,item.ut.title)
    
    结果:
    bb 18 黄金用户
    cc 18 黄金用户

    还可以加条件过滤

    obj = models.UserType.objects.get(id=2)
        result = obj.userinfo_set.filter(name='bb')
        #这里的userinfo_set相当于models.UserInfo.objects.filter(ut="黄金用户")
        for item in result:
            print(item.name,item.age,item.ut.title)
    
    
    结果:
    bb 18 黄金用户

      数据库多对多操作

     1.自动方式创建第三张表

    (1)创建管理用户和主机两张表,自动生成第三张关系表

    from django.db import models
    
    class Host(models.Model):
        hostname = models.CharField(max_length=32)
        port = models.IntegerField()
    
    class HostAdmin(models.Model):
        username = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        host = models.ManyToManyField('Host')  

    (2)添加主机信息和管理用户信息

    #添加主机信息
    def add_host(request):
        models.Host.objects.create(hostname='host1',port=80)
        models.Host.objects.create(hostname='host2',port=80)
        models.Host.objects.create(hostname='host3',port=80)
        models.Host.objects.create(hostname='host4',port=80)
        return HttpResponse('ok')
    
    #添加管理用户信息
    def add_hostadmin(request):
        models.HostAdmin.objects.create(username='aa',email='11.com')
        models.HostAdmin.objects.create(username='bb',email='22.com')
        models.HostAdmin.objects.create(username='cc',email='33.com')
        models.HostAdmin.objects.create(username='dd',email='44.com')
        return HttpResponse('ok')

    效果如下:

    (3)添加第三张关系表

     正向添加数据

    #添加第三张表信息,使管理用户与主机关联
    def user_info(request):
        # 第一步找到用户
        admin_obj = models.HostAdmin.objects.get(username='bb')
        #第二步找到主机
        host_list = models.Host.objects.filter(id__lt=3)
        #第三步,通过找到的admin_obj对象.add去添加主机
        admin_obj.host.add(*host_list)
    
        return HttpResponse('ok')

    效果如下:

    用户‘’bb“(用户id=2)就跟主机‘1’和‘2’(主机id=(1,2))关联起来了

     反向添加数据

    def user_info(request):
        host_obj = models.Host.objects.get(id=3)
        admmin_list = models.HostAdmin.objects.filter(id__gt=1)
        host_obj.hostadmin_set.add(*admmin_list)
    
        return HttpResponse('ok')

    效果如下:

    总之,不管是正向添加还是反向添加,都是基于主机表或者用户表的一行数据对应另一张表中的一行或多行数据!

    2.手动方式创建第三张表

     (1)创建

    手动创建就是告诉django不要自动创建表了

    from django.db import models
    
    class HostInfo(models.Model):
        hostname = models.CharField(max_length=32)
        port = models.IntegerField()
    
    class UserMap(models.Model):
        username = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        # through告诉Django用那张表做关联
        host = models.ManyToManyField(HostInfo, through='HostRelation')
    
    class HostRelation(models.Model):
        host = models.ForeignKey('HostInfo')
        user = models.ForeignKey('UserMap')

    效果如下:

    (2)添加用户和主机

    from django.shortcuts import render,HttpResponse
    from app02 import models
    
    def user_info(request):
        models.HostInfo.objects.create(hostname='host1',port=80)
        models.HostInfo.objects.create(hostname='host2',port=80)
        models.HostInfo.objects.create(hostname='host3',port=80)
        models.HostInfo.objects.create(hostname='host4',port=80)
        models.UserMap.objects.create(username='aa',email='11.com')
        models.UserMap.objects.create(username='bb',email='22.com')
        models.UserMap.objects.create(username='cc',email='33.com')
        models.UserMap.objects.create(username='dd',email='44.com')
    
        return HttpResponse('ok')

    (3)给第三张表添加数据

    当使用自定义方式时,第三张关系表数据直接添加就可以,不需要管另外两张表

    def user_info(request):
    
        models.HostRelation.objects.create(
            host_id = 2,
            user_id = 2
        )
        return HttpResponse('ok')

    效果:

      models.HostRelation.objects.create(
            host_id = 1,
            user_id = 1
        )
        models.HostRelation.objects.create(
            host_id=3,
            user_id=1
        )
    添加多个

    (4)查找

    通过自定义方式,查找直接查就可以,不存在正向反向,更方便

    def user_info(request):
        relation_list = models.HostRelation.objects.all()
        for item in relation_list:
            print(item.user.username)
            print(item.host.hostname)
        
        return HttpResponse('ok')
    结果:
    bb
    host2
    aa
    host1
    aa
    host3
    def user_info(request):
        relation_list = models.HostRelation.objects.filter(user__username='bb')
        for item in relation_list:
            print(item.user.username)
            print(item.host.hostname)
        return HttpResponse('ok')

     ORM的F&Q

     1.F

    F的作用:用来批量修改数据的

     比如:把上面hostinfo表所有port从80改成90

    models.HostInfo.objects.all().update(port=F('port')+10)

    要先导入模块

    from django.db.models import F

    2.Q

     Q的作用:Q是用来做条件查询的

  • 相关阅读:
    Linux下mysql使用systemctl restart mysqld命令失败
    Linux环境下mysql报错:bash: mysql: command not found 的解决方法
    Linux查看mysql是否启动的命令
    启动MySQL5.7时报错:initialize specified but the data directory has files in it. Aborting.
    ARM64架构下面安装mysql5.7.22
    Python3.6打开EAIDK-610开发板(计算机通用)摄像头拍照并保存
    Python的几种主动结束程序方式
    aarch64架构下安装tensorflow详细过程
    python代码在linux终端中执行报错:Unable to init server: Could not connect: Connection refused
    red hat 报错:apt-get:找不到命令
  • 原文地址:https://www.cnblogs.com/gaidy/p/11887047.html
Copyright © 2011-2022 走看看