• 一对一,多对多,数据表类型mysql和orm的区别,django-admin ,内置分页,自定义分页


    表对表的一对一多对一关系

    1. 一对一
            models.py
                oneTooneField
            views.py:
    			##### 从母表查询子表的数据
    			### 反向查询
    			res.子表表名小写.子表的字段名
    						
    			#### 从子表查询母表的数据
    			### 正向查询
    			res.关联字段.母表的字段名
          
    2. 多对多:  
       models.py:
          class Boy(models.Model):
             bname = models.CharField(max_length=32)
          
          class Girl(models.MOdel):
             gname = models.CharField(max_length=32)
             
          class b2g(models.MOdel):
             b  = models.ForeignKey("Boy", null=True)
             g  = models.ForeignKey("Girl", null=True)
       
       views.py:
          bulk_create()      
          添加数据的时候, 两种方式:
             bobj = models.Boy.objects.filter(bname='雷俊').first()
             gobj = models.Girl.objects.filter(gname='乔碧萝').first()
    
             # models.Boy2Girl.objects.create(b_id=bobj.id, g_id=gobj.id)
             models.Boy2Girl.objects.create(b=bobj, g=gobj)
          
          
             1. 自己写第三张表
          查询:
              查询和雷俊约会的姑娘
             #### 需求: 查找一下和雷俊约会的姑娘
             #### 1.
             # res = models.Boy.objects.filter(bname='雷俊').first()
             # love_list = res.boy2girl_set.all()
             # for love in love_list:
             #     print(love.g.gname)
             #
             ##### 2.
             # res = models.Boy2Girl.objects.filter(b__bname='雷俊').all()
             # print(res) ### [obj, obj,....]
             # for love in res:
             #     print(love.g.gname)
             #
             ##### 3.
             # res = models.Boy2Girl.objects.filter(b__bname='雷俊').values('g__gname').all()
             # print(res) ### [{}]
             
             2. 不写第三张表, 使用manytomanyfield
             
                models.py:
                   class Boy(models.Model):
                      bname = models.CharField(max_length=32, null=True)
                      g = models.ManyToManyField('Girl', null=True)
                   class Girl(models.Model):
                      gname = models.CharField(max_length=32, null=True)
                
                views.py:
                       res = models.Boy.objects.filter(bname='雷俊').first()
                      ### 添加
                      # res.g.add(1)
                      # res.g.add(2,3)
                      ### 删除
                      # res.g.remove(3)
    
                      ### 查询
                      # res = models.Boy.objects.filter(bname='雷俊').first()
                      # print(res.g.all())  ####
    
                      ### 清除
                      res.g.clear() ### 清空所有的记录
             
             推荐:
                第一种
                
                因为第二种方式, 字段只能生成两个, 将来扩展的时候, 很不方便,需要重新打破字段
    
                因此还是使用第一种方式,自定义创建第三张表
       
    

    数据表类型

    数字 mysql orm
    tinyint 不存在
    smallint SmallIntegerField
    mediumint 不存在
    int(unsigned) IntegerField PositiveIntegerField
    bigint BigIntegerField PositiveIntegerField
    decimal DecimalField
    float FloatField
    字符串 char 不存在
    varchar Charfield
    text TextField
    时间 Date DateField
    Datetime(2019-8-16 12:23:34 DatetimeField

    参数

          null : 是否为null
          default: 默认值
          primary_key: 是否为主键
          db_index: 普通索引
          unique: 唯一索引
          db_column: 列名
          
       class Meta:
          ### 联合唯一索引
          unique_together = [
             ("b", 'g')
          ]
          ### 联合索引:
          index_together = [
             ('b', 'g')
          ]
          
    

    Django-admin:

    首先先在里面添加内容:(在terminal >>>createsuperuser --用户名--密码)

    from django.contrib import admin
    # Register your models here.
    from classes import models
    admin.site.register(models.Test)
    
    
    - django admin 数据类型中:(不是重点)
                EmailField(CharField):(常用)
                - 字符串类型,Django Admin以及ModelForm中提供验证机制
                IPAddressField(Field):(常用)
                - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
             GenericIPAddressField(Field)
                - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
                - 参数:
                   protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                   unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
             URLField(CharField)
                - 字符串类型,Django Admin以及ModelForm中提供验证 URL
             SlugField(CharField)
                - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
             CommaSeparatedIntegerField(CharField)
                - 字符串类型,格式必须为逗号分割的数字
             UUIDField(Field)
                - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
             FilePathField(Field)
                - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
                - 参数:
                      path,                      文件夹路径
                      match=None,                正则匹配
                      recursive=False,           递归下面的文件夹
                      allow_files=True,          允许文件
                      allow_folders=False,       允许文件夹
             FileField(Field)(常用)
                - 字符串,路径保存在数据库,文件上传到指定目录
                - 参数:
                   upload_to = ""      上传文件的保存路径
                   storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
             ImageField(FileField)
                - 字符串,路径保存在数据库,文件上传到指定目录
                - 参数:
                   upload_to = ""      上传文件的保存路径
                   storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
                   width_field=None,   上传图片的高度保存的数据库字段名(字符串)
                   height_field=None   上传图片的宽度保存的数据库字段名(字符串)
    
          
          - django admin 参数: 
               verbose_name(常用)         Admin中显示的中文列名
                blank(常用)               Admin中是否允许用户输入为空
                editable            Admin中是否可以编辑
                help_text(常用)          Admin中该字段的提示信息
                choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                               如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=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_112233d+', message='又错误了', code='c2'),
                                        EmailValidator(message='又错误了', code='c3'), ]
                                  )
             
    
    1. 分页:

      • 内置分页
        res = Paginator(要分页的数据列表,每页显示的数据)

        users = res.page(当前页码) #### 当前页码的所有数据和属性

        缺点:
        只能将所有的页码循环的展示

    views.py:
        def test2(request):
        # for i in range(296):
        #     name='root'+str(i)
        #     models.UserInfo.objects.create(name=name,age=20)
        cur_page = request.GET.get('cur_page')  ### 1
    
    
        userlist = models.UserInfo.objects.all()
    
        from django.core.paginator import Paginator
        #
        # # per_page: 每页显示条目数量
        # # count:    数据总个数
        # # num_pages:总页数
        # # page_range:总页数的索引范围,如: (1,10),(1,200)
        # # page:     page对象
        paginator = Paginator(userlist, 10)
        #
        # # has_next              是否有下一页
        # # next_page_number      下一页页码
        # # has_previous          是否有上一页
        # # previous_page_number  上一页页码
        # # object_list           分页之后的数据列表
        # # number                当前页
        # # paginator             paginator对象
        users = paginator.page(cur_page)
    
        return render(request, 'index.html', {'users':users})
    
    index.html:
    
    <ul>
        {% for user in users.object_list %}
            <li>{{ user.name }}</li>
    
        {% endfor %}
    
        {% if users.has_previous %}
            <a href="/test2/?cur_page={{ users.previous_page_number }}">上一页</a>
        {% endif %}
    
        {% for num in users.paginator.page_range %}
            <a href="/test2/?cur_page={{ num }}">{{ num }}</a>
        {% endfor %}
        {% if users.has_next %}
            <a href="/test2/?cur_page={{ users.next_page_number }}">下一页</a>
        {% endif %}
    
    </ul>
    </body>
    </html>
    
    
    
    • 自定义分页:
    views.py:
    class PageInfo():
        def __init__(self, cur_page, total, per_page=10, show_page=11):
            self.cur_page = cur_page
            self.per_page = per_page
            self.total = total
            self.show_page = show_page
    
            a, b = divmod(self.total, self.per_page)
            if b:
                a = a + 1
            self.total_page = a   #### 总页数
    
        #### 获取起始索引
        def get_start(self):
            start = (self.cur_page - 1) * self.per_page
            return start
        #### 获取结束索引
        def get_end(self):
            return self.cur_page * self.per_page
    
        def get_page(self):
    
            half  = (self.show_page - 1) // 2
    
            #### taotal_page = 5 < show_page = 11
            if self.total_page < self.show_page:
                begin = 1
                end = self.total_page
            else:
                #### 左边极值判断
                if self.cur_page - half <= 0 :
                    begin = 1
                    # end = self.cur_page + half
                    end = self.show_page
                #### 右边极值的判断
                elif self.cur_page + half > self.total_page:
                    # begin =  self.cur_page - half
                    begin =  self.total_page - self.show_page + 1
                    end = self.total_page   ### 31
                #### 正常页码判断
                else:
                    begin = self.cur_page - half
                    end = self.cur_page + half
    
            page_list = []
            if self.cur_page == 1:
                astr = "<li><a href='#' aria-label='Previous'><span aria-hidden='true'>&laquo;</span></a></li>"
            else:
                astr = "<li><a href='/custom/?cur_page=%s' aria-label='Previous'><span aria-hidden='true'>&laquo;</span></a></li>" % (self.cur_page-1)
            page_list.append(astr)
    
            for i in range(begin, end + 1):
                if self.cur_page == i:
                    # astr = "<a style='display:inline-block; padding:5px;margin:5px;background-color:red;' href='/custom/?cur_page=%s'>%s</a>" % (i, i)
                    astr = "<li class='active'><a href='/custom/?cur_page=%s'>%s</a></li>" % (i, i)
                else:
                    # astr = "<a style='display:inline-block; padding:5px;margin:5px' href='/custom/?cur_page=%s'>%s</a>" % (i, i)
                    astr = "<li><a href='/custom/?cur_page=%s'>%s</a></li>" % (i, i)
                page_list.append(astr)
    
            if self.cur_page == self.total_page:
                astr = "<li><a href='#' aria-label='Next'><span aria-hidden='true'>&raquo;</span></a></li>"
            else:
                astr = "<li><a href='/custom/?cur_page=%s' aria-label='Next'><span aria-hidden='true'>&raquo;</span></a></li>" % (self.cur_page+1)
            page_list.append(astr)
    
            s = " ".join(page_list)
    
            return s
    
    def custom(request):
    
        cur_page = request.GET.get('cur_page')
        cur_page = int(cur_page)
    
        '''
        mysql:
           seelct * from userinfo limit 0, 10 
           seelct * from userinfo limit 10, 10 
           
           cur_page    start   show_page
              1          0     10
              2          10    10
              3          20    10
              n         (n-1)*10, 10
        limit (cur_page - 1) * show_page 
        '''
        # total = models.UserInfo.objects.count()
        total = models.UserInfo.objects.filter(id__lte=44).count()
        page = PageInfo(cur_page, total)
        start = page.get_start()
        end =  page.get_end()
    
        ### cur_page = 1   start = 0   end = 10
        ### cur_page = 2   start = 10  end = 20
        ### cur_page = 3   start  =20  end = 30
        # user_list = models.UserInfo.objects.all()[start:end]
        user_list = models.UserInfo.objects.filter(id__lte=44)[start:end]
        return render(request, "custom.html", {"user_list":user_list, "page":page})
    
    
    
    
    custom.html:
        
        
        <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Title</title>
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
        <ul>
            {% for user in user_list %}
                <li>{{ user.name }}</li>
            {% endfor %}
        </ul>
    
    
        <nav aria-label="Page navigation">
          <ul class="pagination">
              {{ page.get_page | safe}}
          </ul>
        </nav>
    </body>
    </html>
    
  • 相关阅读:
    Android Studio 字体和字号调整
    【IDEA】项目中引入Spring MVC
    【Double】double精度问题和int、long除不尽取舍问题
    【进制转换】原码反码和补码的理解以及进制转换
    【工具】SwitchHost的使用
    【工具】谷歌浏览器使用技巧
    【Git和GitHub】学习笔记
    【IE兼容性】代码中多语言样式+IE不兼容解决
    【Trello】使用指南
    【实操】进制转换:除基倒取余法
  • 原文地址:https://www.cnblogs.com/zhuyuanying123--/p/11365215.html
Copyright © 2020-2023  润新知