一对一,多对多,数据表类型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() ### 清空所有的记录
         
         推荐:
            第一种
            
            因为第二种方式, 字段只能生成两个, 将来扩展的时候, 很不方便,需要重新打破字段

            因此还是使用第一种方式,自定义创建第三张表
   

数据表类型

数字mysqlorm
tinyint不存在
smallintSmallIntegerField
mediumint不存在
int(unsigned)IntegerField PositiveIntegerField
bigintBigIntegerField PositiveIntegerField
decimalDecimalField
floatFloatField
字符串char不存在
varcharCharfield
textTextField
时间DateDateField
Datetime(2019-8-16 12:23:34DatetimeField
参数
      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_112233\d+', 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>

转载于:https://www.cnblogs.com/zhuyuanying123--/p/11365215.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值