django框架:

  Models

1、基本创建

Django提供了一个抽象层("Model")的构建和管理Web应用程序的数据。

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

  • 每个模型是一个Python类,子类django.db.models.model
  • 模型中的每个属性代表一个数据库字段。
  1. # DEMO
  2.  
  3. class Student(models.Model):
  4. name = models.CharField(max_length=10)
  5. sex = models.CharField(max_length=10)
  6. age = models.IntegerField()
  7. grade = models.ForeignKey('Grade')
  1. AutoField(Field)
  2. - int自增列,必须填入参数 primary_key=True
  3.  
  4. BigAutoField(AutoField)
  5. - bigint自增列,必须填入参数 primary_key=True
  6.  
  7. 注:当model中如果没有自增列,则自动会创建一个列名为id的列
  8. from django.db import models
  9.  
  10. class UserInfo(models.Model):
  11. # 自动创建一个列名为id的且为自增的整数列
  12. username = models.CharField(max_length=32)
  13.  
  14. class Group(models.Model):
  15. # 自定义自增列
  16. nid = models.AutoField(primary_key=True)
  17. name = models.CharField(max_length=32)
  18.  
  19. SmallIntegerField(IntegerField):
  20. - 小整数 -32768 32767
  21.  
  22. PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
  23. - 正小整数 0 32767
  24. IntegerField(Field)
  25. - 整数列(有符号的) -2147483648 2147483647
  26.  
  27. PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
  28. - 正整数 0 2147483647
  29.  
  30. BigIntegerField(IntegerField):
  31. - 长整型(有符号的) -9223372036854775808 9223372036854775807
  32.  
  33. 自定义无符号整数字段
  34.  
  35. class UnsignedIntegerField(models.IntegerField):
  36. def db_type(self, connection):
  37. return 'integer UNSIGNED'
  38.  
  39. PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
  40. 'AutoField': 'integer AUTO_INCREMENT',
  41. 'BigAutoField': 'bigint AUTO_INCREMENT',
  42. 'BinaryField': 'longblob',
  43. 'BooleanField': 'bool',
  44. 'CharField': 'varchar(%(max_length)s)',
  45. 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
  46. 'DateField': 'date',
  47. 'DateTimeField': 'datetime',
  48. 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
  49. 'DurationField': 'bigint',
  50. 'FileField': 'varchar(%(max_length)s)',
  51. 'FilePathField': 'varchar(%(max_length)s)',
  52. 'FloatField': 'double precision',
  53. 'IntegerField': 'integer',
  54. 'BigIntegerField': 'bigint',
  55. 'IPAddressField': 'char(15)',
  56. 'GenericIPAddressField': 'char(39)',
  57. 'NullBooleanField': 'bool',
  58. 'OneToOneField': 'integer',
  59. 'PositiveIntegerField': 'integer UNSIGNED',
  60. 'PositiveSmallIntegerField': 'smallint UNSIGNED',
  61. 'SlugField': 'varchar(%(max_length)s)',
  62. 'SmallIntegerField': 'smallint',
  63. 'TextField': 'longtext',
  64. 'TimeField': 'time',
  65. 'UUIDField': 'char(32)',
  66.  
  67. BooleanField(Field)
  68. - 布尔值类型
  69.  
  70. NullBooleanField(Field):
  71. - 可以为空的布尔值
  72.  
  73. CharField(Field)
  74. - 字符类型
  75. - 必须提供max_length参数, max_length表示字符长度
  76.  
  77. TextField(Field)
  78. - 文本类型
  79.  
  80. EmailField(CharField):
  81. - 字符串类型,Django Admin以及ModelForm中提供验证机制
  82.  
  83. IPAddressField(Field)
  84. - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
  85.  
  86. GenericIPAddressField(Field)
  87. - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4Ipv6
  88. - 参数:
  89. protocol,用于指定Ipv4Ipv6 'both',"ipv4","ipv6"
  90. unpack_ipv4 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
  91.  
  92. URLField(CharField)
  93. - 字符串类型,Django Admin以及ModelForm中提供验证 URL
  94.  
  95. SlugField(CharField)
  96. - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
  97.  
  98. CommaSeparatedIntegerField(CharField)
  99. - 字符串类型,格式必须为逗号分割的数字
  100.  
  101. UUIDField(Field)
  102. - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
  103.  
  104. FilePathField(Field)
  105. - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
  106. - 参数:
  107. path, 文件夹路径
  108. match=None, 正则匹配
  109. recursive=False, 递归下面的文件夹
  110. allow_files=True, 允许文件
  111. allow_folders=False, 允许文件夹
  112.  
  113. FileField(Field)
  114. - 字符串,路径保存在数据库,文件上传到指定目录
  115. - 参数:
  116. upload_to = "" 上传文件的保存路径
  117. storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
  118.  
  119. ImageField(FileField)
  120. - 字符串,路径保存在数据库,文件上传到指定目录
  121. - 参数:
  122. upload_to = "" 上传文件的保存路径
  123. storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
  124. width_field=None, 上传图片的高度保存的数据库字段名(字符串)
  125. height_field=None 上传图片的宽度保存的数据库字段名(字符串)
  126.  
  127. DateTimeField(DateField)
  128. - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
  129.  
  130. DateField(DateTimeCheckMixin, Field)
  131. - 日期格式 YYYY-MM-DD
  132.  
  133. TimeField(DateTimeCheckMixin, Field)
  134. - 时间格式 HH:MM[:ss[.uuuuuu]]
  135.  
  136. DurationField(Field)
  137. - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
  138.  
  139. FloatField(Field)
  140. - 浮点型
  141.  
  142. DecimalField(Field)
  143. - 10进制小数
  144. - 参数:
  145. max_digits,小数总长度
  146. decimal_places,小数位长度
  147.  
  148. BinaryField(Field)
  149. - 二进制类

字段

  1. null 数据库中字段是否可以为空
  2. db_column 数据库中字段的列名
  3. db_tablespace
  4. default 数据库中字段的默认值
  5. primary_key 数据库中字段是否为主键
  6. db_index 数据库中字段是否可以建立索引
  7. unique 数据库中字段是否可以建立唯一索引
  8. unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引
  9. unique_for_month 数据库中字段【月】部分是否可以建立唯一索引
  10. unique_for_year 数据库中字段【年】部分是否可以建立唯一索引
  11.  
  12. verbose_name Admin中显示的字段名称
  13. blank Admin中是否允许用户输入为空
  14. editable Admin中是否可以编辑
  15. help_text Admin中该字段的提示信息
  16. choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
  17. 如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
  18.  
  19. error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息;
  20. 字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
  21. 如:{'null': "不能为空.", 'invalid': '格式错误'}
  22.  
  23. validators 自定义错误验证(列表类型),从而定制想要的验证规则
  24. from django.core.validators import RegexValidator
  25. from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
  26. MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
  27. 如:
  28. test = models.CharField(
  29. max_length=32,
  30. error_messages={
  31. 'c1': '优先错信息1',
  32. 'c2': '优先错信息2',
  33. 'c3': '优先错信息3',
  34. },
  35. validators=[
  36. RegexValidator(regex='root_\d+', message='错误了', code='c1'),
  37. RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
  38. EmailValidator(message='又错误了', code='c3'), ]
  39. )

Field参数

2、连表结构例如在建表的时候应该了解到如何

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

3、表操作

a、基本操作

  1. # 增
  2. #
  3. # models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs
  4.  
  5. # obj = models.Tb1(c1='xx', c2='oo')
  6. # obj.save()
  7.  
  8. # 查
  9. #
  10. # models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不建议)
  11. # models.Tb1.objects.all() # 获取全部
  12. # models.Tb1.objects.filter(name='seven')# 获取指定条件的数据
  13.  
  14. # 删
  15. #
  16. # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据
  17.  
  18. # 改
  19. # models.Tb1.objects.filter(name='seven').update(gender='0') # 将指定条件的数据更新,均支持 **kwargs
  20. # obj = models.Tb1.objects.get(id=1)
  21. # obj.c1 = '111'
  22. # obj.save() # 修改单条数据

b、进阶操作(了不起的双下划线)

  1. # 获取个数
  2. #
  3. # models.Tb1.objects.filter(name='seven').count()
  4.  
  5. # 大于,小于
  6. #
  7. # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
  8. # models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
  9. # models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
  10. # models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
  11. # models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
  12.  
  13. # in
  14. #
  15. # models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
  16. # models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
  17.  
  18. # isnull
  19. # Entry.objects.filter(pub_date__isnull=True)
  20.  
  21. # contains
  22. #
  23. # models.Tb1.objects.filter(name__contains="ven")
  24. # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
  25. # models.Tb1.objects.exclude(name__icontains="ven")
  26.  
  27. # range
  28. #
  29. # models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and
  30.  
  31. # 其他类似
  32. #
  33. # startswith,istartswith, endswith, iendswith,
  34.  
  35. # order by
  36. #
  37. # models.Tb1.objects.filter(name='seven').order_by('id') # asc
  38. # models.Tb1.objects.filter(name='seven').order_by('-id') # desc
  39.  
  40. # group by
  41. #
  42. # from django.db.models import Count, Min, Max, Sum
  43. # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
  44. # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
  45.  
  46. # limit 、offset
  47. #
  48. # models.Tb1.objects.all()[10:20]
  49.  
  50. # regex正则匹配,iregex 不区分大小写
  51. #
  52. # Entry.objects.get(title__regex=r'^(An?|The) +')
  53. # Entry.objects.get(title__iregex=r'^(an?|the) +')
  54.  
  55. # date
  56. #
  57. # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
  58. # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
  59.  
  60. # year
  61. #
  62. # Entry.objects.filter(pub_date__year=2005)
  63. # Entry.objects.filter(pub_date__year__gte=2005)
  64.  
  65. # month
  66. #
  67. # Entry.objects.filter(pub_date__month=12)
  68. # Entry.objects.filter(pub_date__month__gte=6)
  69.  
  70. # day
  71. #
  72. # Entry.objects.filter(pub_date__day=3)
  73. # Entry.objects.filter(pub_date__day__gte=3)
  74.  
  75. # week_day
  76. #
  77. # Entry.objects.filter(pub_date__week_day=2)
  78. # Entry.objects.filter(pub_date__week_day__gte=2)
  79.  
  80. # hour
  81. #
  82. # Event.objects.filter(timestamp__hour=23)
  83. # Event.objects.filter(time__hour=5)
  84. # Event.objects.filter(timestamp__hour__gte=12)
  85.  
  86. # minute
  87. #
  88. # Event.objects.filter(timestamp__minute=29)
  89. # Event.objects.filter(time__minute=46)
  90. # Event.objects.filter(timestamp__minute__gte=29)
  91.  
  92. # second
  93. #
  94. # Event.objects.filter(timestamp__second=31)
  95. # Event.objects.filter(time__second=2)
  96. # Event.objects.filter(timestamp__second__gte=31)

进阶之双下划线

c、连表操作(了不起的双下划线)

  1. # DEMO
  2. # 班级和老师存在多对多关系、班级和学生存在一对多关系
  3. from django.db import models
  4.  
  5. class Classes(models.Model):
  6. titile = models.CharField(max_length=32)
  7. m = models.ManyToManyField('Teachers')
  8.  
  9. class Teachers(models.Model):
  10. name = models.CharField (max_length=32)
  11.  
  12. class Student(models.Model):
  13. username = models.CharField(max_length=32)
  14. age = models.IntegerField()
  15. gender = models.BooleanField()
  16. cs = models.ForeignKey(Classes)

表结构实例

  1. # 增
  2. # Teachers.objects.create(name='root')
  3. # obj = Teachers(name='root')
  4. # obj.save()
  5. # 查
  6. # Teachers.objects.all()
  7. # Teachers.objects.filter(id=1)
  8. # Teachers.objects.filter(id=1,name='root')
  9. # result = Teachers.objects.filter(id__gt=1)
  10. # [obj(id,name),]
  11. # result = Teachers.objects.filter(id__gt=1).first()
  12. # 删
  13. # Teachers.objects.filter(id=1).delete()
  14. # 改
  15. # Teachers.objects.all().update(name='alex')
  16. # Teachers.objects.filter(id=1).update(name='alex')

单表

  1. # 增加
  2. # Student.objects.create(username='东北',age=18,gender='男',cs_id=1)
  3. # Student.objects.create(username='东北',age=18,gender='男',cs= Classes.objects.filter(id=1).first() )
  4. # 查看
  5. """
  6. ret = Student.objects.all()
  7. # []
  8. # [ obj(..),]
  9. # [ obj(1 东北 18 男 1),obj(2 东北1 118 男 2),obj(..),]
  10. for item in ret:
  11. print(item.id)
  12. print(item.username)
  13. print(item.age)
  14. print(item.gender)
  15. print(item.cs_id)
  16. print(item.cs.id)
  17. print(item.cs.name)
  18. """
  19. # 删除
  20. # Student.objects.filter(id=1).delete()
  21. # Student.objects.filter(cs_id=1).delete()
  22.  
  23. # cid = input('请输入班级ID')
  24. # Student.objects.filter(cs_id=cid).delete()
  25.  
  26. # cname = input('请输入班级名称')
  27. # Student.objects.filter(cs_id=cid).delete()
  28. # Student.objects.filter(cs__name=cname).delete()

一对多

  1. """
  2. 班级:
  3. id title
  4. 3班
  5. 4班
  6. 5班
  7. 老师:
  8. id title
  9. Alex
  10. 老妖
  11. 瞎驴
  12. Eric
  13. 老师班级关系表(类):
  14. id 班级id 老师id
  15. 1 2
  16. 1 3
  17. 2 2
  18. 2 3
  19. 2 4
  20. 1 5
  21.  
  22. # 增
  23. obj = Classes.objects.filter(id=1).first() #1 3班
  24. obj.m.add(2)
  25. obj.m.add([4,3])
  26.  
  27. # obj = Classes.objects.filter(id=2).first() #1 3班
  28. # obj.m.add(2)
  29. # obj.m.add([4,3])
  30.  
  31. obj = Classes.objects.filter(id=1).first() #1 3班
  32. # 删除
  33. # obj.m.remove([4,3])
  34. # 清空
  35. obj.m.clear()
  36. # 重置
  37. obj.m.set([2,3,5])
  38.  
  39. # 查第三张表
  40. # 把3班的所有老师列举
  41. obj = Classes.objects.filter(id=1).frist()
  42. obj.id
  43. obj.titile
  44. ret = obj.m.all() # 第三张表
  45. # ret是一个 [ 老师1(id,name),obj(id,name) ]
  46.  
  47. """

多对多

d、其它操作

  1. # ============其他的关于moders的应用=========================
  2. # 排序
  3. # user_list=models.Userinfo.objects.all().order_by("id","username")#从小到大排序,当出现id一样的话,则按照名字排序
  4. # user_list2=models.Userinfo.objects.all().order_by("-id")#从大到小排序
  5. # print(user_list)
  6. # print(user_list2)
  7. # 分组
  8. from django.db.models import Count,Sum,Min,Max
  9. # res=models.Userinfo.objects.values("ut_id").annotate(a=Count("id"))
  10. # print(res.query)#==>相当于SELECT `app01_userinfo`.`ut_id`, COUNT(`app01_userinfo`.`id`) AS `a` FROM `app01_userinfo` GROUP BY `app01_userinfo`.`ut_id`
  11.  
  12. # res=models.Userinfo.objects.values("ut_id").annotate(b=Count("id")).filter(id__lt=2)
  13. # print(res)#==><QuerySet [{'ut_id': 1, 'b': 1}]>
  14. # print(res.query)#=>SELECT `app01_userinfo`.`ut_id`, COUNT(`app01_userinfo`.`id`) AS `b` FROM `app01_userinfo` WHERE `app01_userinfo`.`id` < 2 GROUP BY `app01_userinfo`.`ut_id` ORDER BY NULL
  15. # 过滤
  16. # res =models.Userinfo.objects.filter(id__lt=5)#小于
  17. # res =models.Userinfo.objects.filter(id__gt=5)#大于
  18. # res =models.Userinfo.objects.filter(id__lte=5)#小于等于
  19. # res =models.Userinfo.objects.filter(id__gte=5)#大于等于
  20. # res =models.Userinfo.objects.filter(id__in=[1,2,3])#id在列表中
  21. # res =models.Userinfo.objects.filter(id__range=[1,3])#id的范围属于1-3(包含1和3)
  22. # res=models.Userinfo.objects.filter(username__startswith="ha")
  23. # res=models.Userinfo.objects.filter(username__endswith="ha")
  24. # res=models.Userinfo.objects.filter(username__contains="xu")#包含
  25. # res=models.Userinfo.objects.exclude(id=1)#排除id=1的
  26. # print(res)
  27.  
  28. # ======关于F、Q、extra
  29. # F:
  30. from django.db.models import F
  31. #将数据库中的年级那一列都自加一
  32. # models.Userinfo.objects.all().update(age=F("age")+1)
  33.  
  34. # Q:
  35. # res=models.Userinfo.objects.filter(id=1,username="xuyuanyuan")#里面是and的关系
  36. # print(res)#==><QuerySet []>
  37. # dict={
  38. # "id":1,
  39. # "username":"xuyuanyuan"
  40. # }#里面是and的关系
  41. # ret=models.Userinfo.objects.filter(**dict)
  42. # print(ret)#===><QuerySet []>
  43.  
  44. from django.db.models import Q
  45. # Q使用有两种方式:对象方式,方法方式 *
  46. # res=models.Userinfo.objects.filter(Q(id__lt=5))
  47. # res=models.Userinfo.objects.filter(Q(id__lt=5)|Q(id__gt=315))#或
  48. # res=models.Userinfo.objects.filter(Q(id__lt=5)&Q(id__gt=310))
  49. # print(res)
  50.  
  51. # q1=Q()
  52. # q1.connector="OR"
  53. # q1.children.append(("id__gte",1))
  54. # q1.children.append(("id",3))
  55. # q1.children.append(("id",4))
  56. #
  57. # q2 = Q()
  58. # q2.connector = 'OR'
  59. # q2.children.append(('id', 11))
  60. # q2.children.append(('id', 1))
  61. # q2.children.append(('id', 10))
  62. #
  63. # q3 = Q()
  64. # q3.connector = 'AND'
  65. # q3.children.append(('id', 111))
  66. # q3.children.append(('id', 200))
  67. # q2.add(q3,'OR')
  68. #
  69. # con = Q()
  70. # con.add(q1, 'AND')
  71. # con.add(q2, 'AND')
  72. # res=models.Userinfo.objects.filter(con)
  73. # print(res)#===><QuerySet [<Userinfo: 1-hahaha-19>]>
  74. # print(res.query)#==>上面定义的就相当于下面的sql语句:
  75. # SELECT `app01_userinfo`.`id`,
  76. # `app01_userinfo`.`username`,
  77. # `app01_userinfo`.`age`,
  78. # `app01_userinfo`.`ut_id`
  79. # FROM `app01_userinfo`
  80. # WHERE ((`app01_userinfo`.`id` >= 1 OR `app01_userinfo`.`id` = 3 OR `app01_userinfo`.`id` = 4)
  81. # AND (`app01_userinfo`.`id` = 11 OR `app01_userinfo`.`id` = 1 OR `app01_userinfo`.`id` = 10
  82. # OR (`app01_userinfo`.`id` = 111 AND `app01_userinfo`.`id` = 200)))
  83.  
  84. # condition_dict = {
  85. # 'k1':[1,2,3,4],
  86. # 'k2':[1,2,10,11],
  87. # "k3":[1,2,100,111,200],
  88. # }
  89. # con = Q()
  90. # for k,v in condition_dict.items():
  91. # q = Q()
  92. # q.connector = 'OR'
  93. # for i in v:
  94. # q.children.append(('id', i))
  95. # con.add(q,'AND')
  96. # res=models.Userinfo.objects.filter(con)
  97. # print(res)
  98. # print(res.query)
  99.  
  100. # extra:额外的
  101. #
  102. # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
  103. # Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
  104. # Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
  105. # Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
  106. # Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
  107.  
  108. #原生sql
  109. # name_map = {'title': 'titles'}
  110. # v1 = models.Userinfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)
  111. # print(v1.query)
  112. # print(v1)
  113. # for i in v1:
  114. # print(i,type(i))

其它

e、补充

  1. # values 取到的是字典集合
  2. # values_list 取到的是没有键的元祖形式
  3.  
  4. # get 只有在能取到一条数据的时候才不会报错(不推荐)
  5. # filter([筛选条件])
  6. # all() 俩者取到的都是Query set集合对象 是可迭代、可切片、索引取值
  7.  
  8. # iterator() ORM的惰性机制
  9. # Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet
  10. # 并不会马上执行sql,而是当调用QuerySet的时候才执行。

示例:

  1. # ==========多对多的练习
  2. # def test(request):
  3. # objs=[
  4. # models.Boy(bname="小凳子"),
  5. # models.Boy(bname="小座子"),
  6. # models.Boy(bname="小李子"),
  7. # models.Boy(bname="小面子"),
  8. #
  9. # ]
  10. # models.Boy.objects.bulk_create(objs,5)
  11.  
  12. # objss=[
  13. # models.Girl(gname="胖胖"),
  14. # models.Girl(gname="矮矮"),
  15. # models.Girl(gname="高高"),
  16. # models.Girl(gname="凶凶"),
  17. # ]
  18. # models.Girl.objects.bulk_create(objss,5)
  19.  
  20. # models.Love.objects.create(b_id=1,g_id=2)
  21. # models.Love.objects.create(b_id=1,g_id=3)
  22. # models.Love.objects.create(b_id=2,g_id=3)
  23. # models.Love.objects.create(b_id=2,g_id=4)
  24. # models.Love.objects.create(b_id=3,g_id=1)
  25. # models.Love.objects.create(b_id=4,g_id=4)
  26.  
  27. #查找小凳子约会的女生名字
  28. # 方法一:(1)
  29. # objs=models.Boy.objects.filter(bname="小凳子").first()#直接取到的是obj,可以直接obj.出来
  30. # love_list_obj = objs.love_set.all()
  31. # for i in love_list_obj:
  32. # print(i.g.gname)
  33. # (2)
  34. # list=models.Boy.objects.filter(bname="小凳子")#取到的是query的,需要for循环出来obj,再obj.出来
  35. # for i in list:
  36. # print(i.bname)
  37. # print(list[0])
  38. # love_list_obj=list[0].love_set.all()
  39. # for i in love_list_obj:
  40. # print(i.g.gname)
  41.  
  42. # 方法二:
  43. # love_list=models.Love.objects.filter(b__bname="小凳子")
  44. # print(love_list)
  45. # for i in love_list:
  46. # print(i.g.gname)
  47.  
  48. # 方法三:
  49. # love_dict = models.Love.objects.filter(b__bname="小凳子").values("g__gname")
  50. # for i in love_dict:
  51. # print(i["g__gname"])
  52.  
  53. # 方法四:
  54. # love_list=models.Love.objects.filter(b__bname="小凳子").select_related("g")
  55. # for i in love_list:
  56. # print(i.g.gname)
  57. #return HttpResponse("hello")

django之model进阶的更多操作整理

一、字段

  1. AutoField(Field)
  2. - int自增列,必须填入参数 primary_key=True
  3.  
  4. BigAutoField(AutoField)
  5. - bigint自增列,必须填入参数 primary_key=True
  6.  
  7. 注:当model中如果没有自增列,则自动会创建一个列名为id的列
  8. from django.db import models
  9.  
  10. class UserInfo(models.Model):
  11. # 自动创建一个列名为id的且为自增的整数列
  12. username = models.CharField(max_length=32)
  13.  
  14. class Group(models.Model):
  15. # 自定义自增列
  16. nid = models.AutoField(primary_key=True)
  17. name = models.CharField(max_length=32)
  18.  
  19. SmallIntegerField(IntegerField):
  20. - 小整数 -32768 32767
  21.  
  22. PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
  23. - 正小整数 0 32767
  24. IntegerField(Field)
  25. - 整数列(有符号的) -2147483648 2147483647
  26.  
  27. PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
  28. - 正整数 0 2147483647
  29.  
  30. BigIntegerField(IntegerField):
  31. - 长整型(有符号的) -9223372036854775808 9223372036854775807
  32.  
  33. BooleanField(Field)
  34. - 布尔值类型
  35.  
  36. NullBooleanField(Field):
  37. - 可以为空的布尔值
  38.  
  39. CharField(Field)
  40. - 字符类型
  41. - 必须提供max_length参数, max_length表示字符长度
  42.  
  43. TextField(Field)
  44. - 文本类型
  45.  
  46. EmailField(CharField):
  47. - 字符串类型,Django Admin以及ModelForm中提供验证机制
  48.  
  49. IPAddressField(Field)
  50. - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
  51.  
  52. GenericIPAddressField(Field)
  53. - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4Ipv6
  54. - 参数:
  55. protocol,用于指定Ipv4Ipv6 'both',"ipv4","ipv6"
  56. unpack_ipv4 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
  57.  
  58. URLField(CharField)
  59. - 字符串类型,Django Admin以及ModelForm中提供验证 URL
  60.  
  61. SlugField(CharField)
  62. - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
  63.  
  64. CommaSeparatedIntegerField(CharField)
  65. - 字符串类型,格式必须为逗号分割的数字
  66.  
  67. UUIDField(Field)
  68. - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
  69.  
  70. FilePathField(Field)
  71. - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
  72. - 参数:
  73. path, 文件夹路径
  74. match=None, 正则匹配
  75. recursive=False, 递归下面的文件夹
  76. allow_files=True, 允许文件
  77. allow_folders=False, 允许文件夹
  78.  
  79. FileField(Field)
  80. - 字符串,路径保存在数据库,文件上传到指定目录
  81. - 参数:
  82. upload_to = "" 上传文件的保存路径
  83. storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
  84.  
  85. ImageField(FileField)
  86. - 字符串,路径保存在数据库,文件上传到指定目录
  87. - 参数:
  88. upload_to = "" 上传文件的保存路径
  89. storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
  90. width_field=None, 上传图片的高度保存的数据库字段名(字符串)
  91. height_field=None 上传图片的宽度保存的数据库字段名(字符串)
  92.  
  93. DateTimeField(DateField)
  94. - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
  95.  
  96. DateField(DateTimeCheckMixin, Field)
  97. - 日期格式 YYYY-MM-DD
  98.  
  99. TimeField(DateTimeCheckMixin, Field)
  100. - 时间格式 HH:MM[:ss[.uuuuuu]]
  101.  
  102. DurationField(Field)
  103. - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
  104.  
  105. FloatField(Field)
  106. - 浮点型
  107.  
  108. DecimalField(Field)
  109. - 10进制小数
  110. - 参数:
  111. max_digits,小数总长度
  112. decimal_places,小数位长度
  113.  
  114. BinaryField(Field)
  115. - 二进制类型

字段列表

  1. class UnsignedIntegerField(models.IntegerField):
  2. def db_type(self, connection):
  3. return 'integer UNSIGNED'
  4.  
  5. PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
  6. 'AutoField': 'integer AUTO_INCREMENT',
  7. 'BigAutoField': 'bigint AUTO_INCREMENT',
  8. 'BinaryField': 'longblob',
  9. 'BooleanField': 'bool',
  10. 'CharField': 'varchar(%(max_length)s)',
  11. 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
  12. 'DateField': 'date',
  13. 'DateTimeField': 'datetime',
  14. 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
  15. 'DurationField': 'bigint',
  16. 'FileField': 'varchar(%(max_length)s)',
  17. 'FilePathField': 'varchar(%(max_length)s)',
  18. 'FloatField': 'double precision',
  19. 'IntegerField': 'integer',
  20. 'BigIntegerField': 'bigint',
  21. 'IPAddressField': 'char(15)',
  22. 'GenericIPAddressField': 'char(39)',
  23. 'NullBooleanField': 'bool',
  24. 'OneToOneField': 'integer',
  25. 'PositiveIntegerField': 'integer UNSIGNED',
  26. 'PositiveSmallIntegerField': 'smallint UNSIGNED',
  27. 'SlugField': 'varchar(%(max_length)s)',
  28. 'SmallIntegerField': 'smallint',
  29. 'TextField': 'longtext',
  30. 'TimeField': 'time',
  31. 'UUIDField': 'char(32)',

自定义无符号整数字段

二、字段参数

  1. null 数据库中字段是否可以为空
  2. db_column 数据库中字段的列名
  3. default 数据库中字段的默认值
  4. primary_key 数据库中字段是否为主键
  5. db_index 数据库中字段是否可以建立索引
  6. unique 数据库中字段是否可以建立唯一索引
  7. unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引
  8. unique_for_month 数据库中字段【月】部分是否可以建立唯一索引
  9. unique_for_year 数据库中字段【年】部分是否可以建立唯一索引
  10.  
  11. verbose_name Admin中显示的字段名称
  12. blank Admin中是否允许用户输入为空
  13. editable Admin中是否可以编辑
  14. help_text Admin中该字段的提示信息
  15. choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
  16. 如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
  17.  
  18. error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息;
  19. 字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
  20. 如:{'null': "不能为空.", 'invalid': '格式错误'}
  21.  
  22. validators 自定义错误验证(列表类型),从而定制想要的验证规则
  23. from django.core.validators import RegexValidator
  24. from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
  25. MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
  26. 如:
  27. test = models.CharField(
  28. max_length=32,
  29. error_messages={
  30. 'c1': '优先错信息1',
  31. 'c2': '优先错信息2',
  32. 'c3': '优先错信息3',
  33. },
  34. validators=[
  35. RegexValidator(regex='root_\d+', message='错误了', code='c1'),
  36. RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
  37. EmailValidator(message='又错误了', code='c3'), ]
  38. )

三、多表关系及参数

  1. ForeignKey(ForeignObject) # ForeignObject(RelatedField)
  2. to, # 要进行关联的表名
  3. to_field=None, # 要关联的表中的字段名称
  4. on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
  5. - models.CASCADE,删除关联数据,与之关联也删除
  6. - models.DO_NOTHING,删除关联数据,引发错误IntegrityError
  7. - models.PROTECT,删除关联数据,引发错误ProtectedError
  8. - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
  9. - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
  10. - models.SET,删除关联数据,
  11. a. 与之关联的值设置为指定值,设置:models.SET(值)
  12. b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
  13.  
  14. def func():
  15. return 10
  16.  
  17. class MyModel(models.Model):
  18. user = models.ForeignKey(
  19. to="User",
  20. to_field="id"
  21. on_delete=models.SET(func),)
  22. related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
  23. related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
  24. limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
  25. # 如:
  26. - limit_choices_to={'nid__gt': 5}
  27. - limit_choices_to=lambda : {'nid__gt': 5}
  28.  
  29. from django.db.models import Q
  30. - limit_choices_to=Q(nid__gt=10)
  31. - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
  32. - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
  33. db_constraint=True # 是否在数据库中创建外键约束
  34. parent_link=False # 在Admin中是否显示关联数据
  35.  
  36. OneToOneField(ForeignKey)
  37. to, # 要进行关联的表名
  38. to_field=None # 要关联的表中的字段名称
  39. on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
  40.  
  41. ###### 对于一对一 ######
  42. # 1. 一对一其实就是 一对多 + 唯一索引
  43. # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
  44. # 如下会在A表中额外增加一个c_ptr_id列且唯一:
  45. class C(models.Model):
  46. nid = models.AutoField(primary_key=True)
  47. part = models.CharField(max_length=12)
  48.  
  49. class A(C):
  50. id = models.AutoField(primary_key=True)
  51. code = models.CharField(max_length=1)
  52.  
  53. ManyToManyField(RelatedField)
  54. to, # 要进行关联的表名
  55. related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
  56. related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
  57. limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
  58. # 如:
  59. - limit_choices_to={'nid__gt': 5}
  60. - limit_choices_to=lambda : {'nid__gt': 5}
  61.  
  62. from django.db.models import Q
  63. - limit_choices_to=Q(nid__gt=10)
  64. - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
  65. - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
  66. symmetrical=None, # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
  67. # 做如下操作时,不同的symmetrical会有不同的可选字段
  68. models.BB.objects.filter(...)
  69.  
  70. # 可选字段有:code, id, m1
  71. class BB(models.Model):
  72.  
  73. code = models.CharField(max_length=12)
  74. m1 = models.ManyToManyField('self',symmetrical=True)
  75.  
  76. # 可选字段有: bb, code, id, m1
  77. class BB(models.Model):
  78.  
  79. code = models.CharField(max_length=12)
  80. m1 = models.ManyToManyField('self',symmetrical=False)
  81.  
  82. through=None, # 自定义第三张表时,使用字段用于指定关系表
  83. through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
  84. from django.db import models
  85.  
  86. class Person(models.Model):
  87. name = models.CharField(max_length=50)
  88.  
  89. class Group(models.Model):
  90. name = models.CharField(max_length=128)
  91. members = models.ManyToManyField(
  92. Person,
  93. through='Membership',
  94. through_fields=('group', 'person'),
  95. )
  96.  
  97. class Membership(models.Model):
  98. group = models.ForeignKey(Group, on_delete=models.CASCADE)
  99. person = models.ForeignKey(Person, on_delete=models.CASCADE)
  100. inviter = models.ForeignKey(
  101. Person,
  102. on_delete=models.CASCADE,
  103. related_name="membership_invites",
  104. )
  105. invite_reason = models.CharField(max_length=64)
  106. db_constraint=True, # 是否在数据库中创建外键约束
  107. db_table=None, # 默认创建第三张表时,数据库中表的名称

四、更多ORM操作

  1. ##################################################################
  2. # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
  3. ##################################################################
  4.  
  5. def all(self)
  6. # 获取所有的数据对象
  7.  
  8. def filter(self, *args, **kwargs)
  9. # 条件查询
  10. # 条件可以是:参数,字典,Q
  11.  
  12. def exclude(self, *args, **kwargs)
  13. # 条件查询
  14. # 条件可以是:参数,字典,Q
  15.  
  16. def select_related(self, *fields)
  17. 性能相关:表之间进行join连表操作,一次性获取关联的数据。
  18. model.tb.objects.all().select_related()
  19. model.tb.objects.all().select_related('外键字段')
  20. model.tb.objects.all().select_related('外键字段__外键字段')
  21.  
  22. def prefetch_related(self, *lookups)
  23. 性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
  24. # 获取所有用户表
  25. # 获取用户类型表where id in (用户表中的查到的所有用户ID)
  26. models.UserInfo.objects.prefetch_related('外键字段')
  27.  
  28. from django.db.models import Count, Case, When, IntegerField
  29. Article.objects.annotate(
  30. numviews=Count(Case(
  31. When(readership__what_time__lt=treshold, then=1),
  32. output_field=CharField(),
  33. ))
  34. )
  35.  
  36. students = Student.objects.all().annotate(num_excused_absences=models.Sum(
  37. models.Case(
  38. models.When(absence__type='Excused', then=1),
  39. default=0,
  40. output_field=models.IntegerField()
  41. )))
  42.  
  43. def annotate(self, *args, **kwargs)
  44. # 用于实现聚合group by查询
  45.  
  46. from django.db.models import Count, Avg, Max, Min, Sum
  47.  
  48. v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
  49. # SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id
  50.  
  51. v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
  52. # SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
  53.  
  54. v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
  55. # SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
  56.  
  57. def distinct(self, *field_names)
  58. # 用于distinct去重
  59. models.UserInfo.objects.values('nid').distinct()
  60. # select distinct nid from userinfo
  61.  
  62. 注:只有在PostgreSQL中才能使用distinct进行去重
  63.  
  64. def order_by(self, *field_names)
  65. # 用于排序
  66. models.UserInfo.objects.all().order_by('-id','age')
  67.  
  68. def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
  69. # 构造额外的查询条件或者映射,如:子查询
  70.  
  71. Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
  72. Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
  73. Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
  74. Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
  75.  
  76. def reverse(self):
  77. # 倒序
  78. models.UserInfo.objects.all().order_by('-nid').reverse()
  79. # 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序
  80.  
  81. def defer(self, *fields):
  82. models.UserInfo.objects.defer('username','id')

  83. models.UserInfo.objects.filter(...).defer('username','id')
  84. #映射中排除某列数据
  85.  
  86. def only(self, *fields):
  87. #仅取某个表中的数据
  88. models.UserInfo.objects.only('username','id')

  89. models.UserInfo.objects.filter(...).only('username','id')
  90.  
  91. def using(self, alias):
  92. 指定使用的数据库,参数为别名(setting中的设置)
  93.  
  94. ##################################################
  95. # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
  96. ##################################################
  97.  
  98. def raw(self, raw_query, params=None, translations=None, using=None):
  99. # 执行原生SQL
  100. models.UserInfo.objects.raw('select * from userinfo')
  101.  
  102. # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
  103. models.UserInfo.objects.raw('select id as nid from 其他表')
  104.  
  105. # 为原生SQL设置参数
  106. models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,])
  107.  
  108. # 将获取的到列名转换为指定列名
  109. name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
  110. Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
  111.  
  112. # 指定数据库
  113. models.UserInfo.objects.raw('select * from userinfo', using="default")
  114.  
  115. ################### 原生SQL ###################
  116. from django.db import connection, connections
  117. cursor = connection.cursor() # cursor = connections['default'].cursor()
  118. cursor.execute("""SELECT * from auth_user where id = %s""", [1])
  119. row = cursor.fetchone() # fetchall()/fetchmany(..)
  120.  
  121. def values(self, *fields):
  122. # 获取每行数据为字典格式
  123.  
  124. def values_list(self, *fields, **kwargs):
  125. # 获取每行数据为元祖
  126.  
  127. def dates(self, field_name, kind, order='ASC'):
  128. # 根据时间进行某一部分进行去重查找并截取指定内容
  129. # kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
  130. # order只能是:"ASC" "DESC"
  131. # 并获取转换后的时间
  132. - year : 年-01-01
  133. - month: 年-月-01
  134. - day : 年-月-日
  135.  
  136. models.DatePlus.objects.dates('ctime','day','DESC')
  137.  
  138. def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
  139. # 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
  140. # kind只能是 "year", "month", "day", "hour", "minute", "second"
  141. # order只能是:"ASC" "DESC"
  142. # tzinfo时区对象
  143. models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
  144. models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai'))
  145.  
  146. """
  147. pip3 install pytz
  148. import pytz
  149. pytz.all_timezones
  150. pytz.timezone(‘Asia/Shanghai’)
  151. """
  152.  
  153. def none(self):
  154. # 空QuerySet对象
  155.  
  156. ####################################
  157. # METHODS THAT DO DATABASE QUERIES #
  158. ####################################
  159.  
  160. def aggregate(self, *args, **kwargs):
  161. # 聚合函数,获取字典类型聚合结果
  162. from django.db.models import Count, Avg, Max, Min, Sum
  163. result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
  164. ===> {'k': 3, 'n': 4}
  165.  
  166. def count(self):
  167. # 获取个数
  168.  
  169. def get(self, *args, **kwargs):
  170. # 获取单个对象
  171.  
  172. def create(self, **kwargs):
  173. # 创建对象
  174.  
  175. def bulk_create(self, objs, batch_size=None):
  176. # 批量插入
  177. # batch_size表示一次插入的个数
  178. objs = [
  179. models.DDD(name='r11'),
  180. models.DDD(name='r22')
  181. ]
  182. models.DDD.objects.bulk_create(objs, 10)
  183.  
  184. def get_or_create(self, defaults=None, **kwargs):
  185. # 如果存在,则获取,否则,创建
  186. # defaults 指定创建时,其他字段的值
  187. obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '','u_id': 2, 't_id': 2})
  188.  
  189. def update_or_create(self, defaults=None, **kwargs):
  190. # 如果存在,则更新,否则,创建
  191. # defaults 指定创建时或更新时的其他字段
  192. obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '','u_id': 2, 't_id': 1})
  193.  
  194. def first(self):
  195. # 获取第一个
  196.  
  197. def last(self):
  198. # 获取最后一个
  199.  
  200. def in_bulk(self, id_list=None):
  201. # 根据主键ID进行查找
  202. id_list = [11,21,31]
  203. models.DDD.objects.in_bulk(id_list)
  204.  
  205. def delete(self):
  206. # 删除
  207.  
  208. def update(self, **kwargs):
  209. # 更新
  210.  
  211. def exists(self):
  212. # 是否有结果

五、小结

  1. # Model操作
  2. .related_name # 设置反向查找的别名 例如 Book_set ==> xx
  3. .related_query_name # 设置表的别名 例如 Book_set ==> xx_set
  4.  
  5. .all
  6. .values
  7. .values_list
  8. .delete
  9. .filter
  10. .update
  11. .create
  12.  
  13. # 多对多字段操作
  14. .m.add # 添加关系
  15. .m.set # 重置关系
  16. .m.clear # 清空关系
  17. .m.remove # 删除关系
  18.  
  19. .only # 仅取某几列数据
  20. .defer # 排除某几列数据
  21.  
  22. # 执行原生SQL语句的三种方式
  23.  
  24. # from django.db import connection, connections
  25. # cursor = connection.cursor() 或 cursor = connections['default'].cursor()
  26. # cursor.execute("""SELECT * from auth_user where id = %s""", [1]) # 将1进行字符串拼接
  27. # row = cursor.fetchone()
  28.  
  29. models.UserInfo.objects.raw('select id,name from userinfo')
  30.  
  31. Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
  32.  
  33. # 涉及到查表效率
  34. # 在使用all filter 查询表时,涉及到第三张表的查询时、
  35. # 会再次执行查询,数据量很庞大的时候,会影响执行效率、因此下方俩条可较为有效的解决此问题
  36.  
  37. select_related('跨表字段') # 一次连表查询获取所有数据
  38. prefetch_related # 不连表、会进行俩次查询

Admin

Django Amdin是Django提供的一个后台管理页面,改管理页面提供完善的html和css,在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用Django Admin 则需要以下步骤:

  • 创建后台管理员
  • 配置url
  • 注册和配置Django Admin后台管理页面

1、创建后台管理员

  1. python manage.py createsuperuser

2、配置后台管理url

  1. url(r'^admin/', include(admin.site.urls))

3、注册和配置django admin 后台管理页面

A、注册表

  1. from django.contrib import admin
  2.  
  3. from app01 import models
  4.  
  5. admin.site.register(models.UserType)
  6. admin.site.register(models.UserInfo)
  7. admin.site.register(models.UserGroup)
  8. admin.site.register(models.Asset)

B、设置数据表显示名称

  1. class UserType(models.Model):
  2. name = models.CharField(max_length=50)
  3.  
  4. class Meta:
  5. verbose_name = '用户类型'
  6. verbose_name_plural = '用户类型'

C、打开表之后想要看哪些字段作出如下配置

  1. from django.contrib import admin
  2.  
  3. from app01 import models
  4.  
  5. class UserInfoAdmin(admin.ModelAdmin):
  6. list_display = ('username', 'password', 'email') # 放置对应表字段
  7.  
  8. admin.site.register(models.UserInfo,UserInfoAdmin)

D、数据表添加过滤功能(模糊输入查询)

  1. from django.contrib import admin
  2.  
  3. from app01 import models
  4.  
  5. class UserInfoAdmin(admin.ModelAdmin):
  6. list_display = ('username', 'password', 'email')
  7. search_fields = ('username', 'email') # 定义它
  8.  
  9. admin.site.register(models.UserInfo,UserInfoAdmin)

E、快速过滤

  1. from django.contrib import admin
  2.  
  3. from app01 import models
  4.  
  5. class UserInfoAdmin(admin.ModelAdmin):
  6. list_display = ('username', 'password', 'email')
  7. search_fields = ('username', 'email')
  8. list_filter = ('username', 'email')
  9.  
  10. admin.site.register(models.UserInfo,UserInfoAdmin)

F、设置分页和只读字段

  1. from django.contrib import admin
  2. from repository import models
  3.  
  4. class CustomerInfoAdmin(admin.ModelAdmin):
  5. list_display = ['name', 'source', 'contact_type', 'contact', 'consultant', 'status', 'date']
  6. list_filter = ['source', 'consultant', 'status', 'date']
  7. search_fields = ['contact', 'consultant__name']
  8. readonly_fields = ['status','contact'] # 只读字段
  9. filter_horizontal = ['consult_courses',] # 出现炫酷的select切换
  10. list_per_page = 2 # 设置分页,每页显示多少条
  11.  
  12. admin.site.register(models.UserProfile)
  13. admin.site.register(models.Role)
  14. admin.site.register(models.CustomerInfo, CustomerInfoAdmin)
  1.  

分页

一、Django内置分页

示例:

urls.py

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from app01 import views
  4.  
  5. urlpatterns = [
  6.  
  7. # 查看django自带的上一页和下一页
  8. url(r'^index.html$', views.index),
  9.  
  10. ] 

views.py

  1. from django.shortcuts import render,HttpResponse
  2. from django.views import View
  3. from app01 import models
  4. from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
  5. # django自带的分页
  6. def index(request):
  7. """
  8. 分页
  9. :param request:
  10. :return:
  11. """
  12. # 往用户信息的数据表内插入300条用户信息
  13. # for i in range(301):
  14. # name="xuyuanyuan"+str(i)
  15. # models.Userinfo.objects.create(username=name,age=20,ut_id=2)
  16.  
  17. choise_page=request.GET.get("page")
  18. user_list=models.Userinfo.objects.all()
  19. # paginator=Paginator(user_list,10)分页处理,每一页10条数据
  20. paginator=Paginator(user_list,10)
  21. # per_page: 每页显示条目数量
  22. # count: 数据总个数
  23. # num_pages:总页数
  24. # page_range:总页数的索引范围,如: (1,10),(1,200)
  25. # page: page对象
  26.  
  27. try:
  28. result=paginator.page(choise_page)
  29. # print(result)#QuerySet [<Userinfo: Userinfo object>, <Userinfo: Userinfo object>,
  30. # 打印的result是一个个userinfo的对象
  31. # print(result.object_list)
  32. except PageNotAnInteger as e:
  33. result=paginator.page(1)
  34. except EmptyPage as e:
  35. result=paginator.page(1)
  36.  
  37. # has_next 是否有下一页
  38. # next_page_number 下一页页码
  39. # has_previous 是否有上一页
  40. # previous_page_number 上一页页码
  41. # object_list 分页之后的数据列表
  42. # number 当前页
  43. # paginator paginator对象
  44.  
  45. return render(request,"index.html",{"result":result})

 index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h1>用户列表</h1>
  9. <ul>
  10. {% for i in result.object_list %}
  11. <li>姓名:{{ i.username }}</li>
  12. {% endfor %}
  13. </ul>
  14. <div>
  15. {% if result.has_previous %}
  16. <a href="/index.html?page={{ result.previous_page_number }}">上一页</a>
  17. {% endif %}
  18.  
  19. {% if result.has_next %}
  20. <a href="/index.html?page={{ result.next_page_number }}">下一页</a>
  21. {% endif %}
  22. </div>
  23. </body>
  24. </html>

执行结果:

二、Django内置分页的拓展

  1. from django.shortcuts import render
  2. from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
  3.  
  4. user = []
  5. for i in range(1, 1001):
  6. dic = {'name': 'root' + str(i), 'pwd': i}
  7. user.append(dic)
  8.  
  9. class DiyPaginator(Paginator):
  10. def __init__(self, current_page,max_pager_num, *args, **kwargs):
  11. """
  12. :param current_page: 当前页码
  13. :param max_pager_num: 显示页码个数的最大值
  14. :param args:
  15. :param kwargs:
  16. """
  17. self.current_page = int(current_page)
  18. self.max_pager_num = int(max_pager_num)
  19. super(DiyPaginator,self).__init__(*args,**kwargs)
  20.  
  21. def pager_num_range(self):
  22. # 需要的参数
  23. # 当前页码 self.current_page
  24. # 页码数量 self.max_pager_num
  25. # 总页数 self.num_pages
  26.  
  27. # 如果总页数小于页码个数最大值的情况
  28. if self.num_pages < self.max_pager_num:
  29. return range(1,self.num_pages+1) # 返回 从 1 到 总页数
  30.  
  31. # 如果总页数大于页码数量且当前所选页码小于页码数量的一半
  32. part = self.max_pager_num//2
  33. if self.current_page <= part:
  34. return range(1,self.max_pager_num+1) # 返回 从 1 到 页码个数最大值
  35.  
  36. # 如果当前页码加一半的页码 大于 总页数
  37. if (self.current_page+part) > self.num_pages:
  38. # 返回 从总页数-最大页码数 到 总页数 range的用法在此不作解释
  39. # 例如 96页+5页 超出总页数 则返回的范围是 从 总页数-最大页码数量+1 到 总页数+1
  40. return range(self.num_pages-self.max_pager_num+1,self.num_pages+1)
  41.  
  42. # 其余情况从 当前页码减去显示页码的平均值开始 到 当前页码加显示页码的平均值(并加一)结束
  43. return range(self.current_page-part,self.current_page+part+1)
  44.  
  45. def index(request):
  46. p = request.GET.get('page')
  47. start = (int(p)-1)*10
  48. end = int(p)*10
  49. data = user[start:end]
  50. return render(request,'index.html',{'data':data,'user':user})
  51.  
  52. def index1(request):
  53. current_page = request.GET.get('page')
  54. paginator = DiyPaginator(current_page, 9, user, 10)
  55. # Paginator所封装的方法
  56. # per_page: 每页显示条目数量
  57. # count: 数据总个数
  58. # num_pages:总页数
  59. # page_range:总页数的索引范围,如: (1,10),(1,200)
  60. # page: page对象
  61. try:
  62. posts = paginator.page(current_page)
  63. # has_next 是否有下一页
  64. # next_page_number 下一页页码
  65. # has_previous 是否有上一页
  66. # previous_page_number 上一页页码
  67. # object_list 分页之后的数据列表
  68. # number 当前页
  69. # paginator paginator对象
  70. except PageNotAnInteger: # 不是整形数字
  71. posts = paginator.page(1)
  72. except EmptyPage: # 如果是空值
  73. posts = paginator.page(paginator.num_pages)
  74.  
  75. return render(request,'index1.html',{'posts':posts})

扩展内置分页

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <ul>
  9. {% for row in posts.object_list %}
  10. <li>{{ row.name }}-{{ row.pwd }}</li>
  11. {% endfor %}
  12. </ul>
  13. {% include 'include/pager.html' %}
  14. </body>
  15. </html>
  16.  
  17. ##################################
  18. include 组件代码
  19.  
  20. {% if posts.has_previous %}
  21. <a href="/index1?page={{ posts.previous_page_number }}">上一页</a>
  22. {% endif %}
  23.  
  24. {% for num in posts.paginator.pager_num_range %}
  25. {% if num == posts.number %}
  26. <a style="color: red;font-size: 20px" href="/index1?page={{ num }}">{{ num }}</a>
  27. {% else %}
  28. <a href="/index1?page={{ num }}">{{ num }}</a>
  29. {% endif %}
  30. {% endfor %}
  31.  
  32. {% if posts.has_next %}
  33. <a href="/index1?page={{ posts.next_page_number }}">下一页</a>
  34. {% endif %}
  35. <span>
  36. 当前页:{{ posts.number }}&nbsp;&nbsp;总页数:{{ posts.paginator.num_pages }}
  37. </span>

扩展内置分页:HTML

三、自定义分页(适用于任何地方)

  • 创建处理分页数据的类
  • 根据分页数据获取数据
  • 输出分页HTML,即:[上一页][1][2][3][4][5][下一页]或者额外的作出一些拓展也可以

创建处理分页数据的类时,大致也需要四个参数(详情观看类构造方法)

  1、为了减少服务器内存的负载,不再获取所有数据的,而是获得所有数据的总个数,然后再根据索引查数据库的内容

  2、当前页码

  3、每页显示的行数

  4、页码显示的数量

对于页数的显示大致也可以归类为三种情况(详情观看类中page_num_range函数)

  1、计算的总页数小于页码显示的数量

  2、计算的总页数大于页码显示的数量

    A、当前页数小于页码数量的一半

    B、当前页数加页码数量的一半超出总页数的范围

  3、正常情况

    从 当前页数 减 一半页码数量 到 当前页数 加 一半页码数量

示例:

首先,先建一个文件包取名为utils,并在改文件包下建一个pager.py的文件:

views.py

  1. from django.shortcuts import render,HttpResponse
  2. from django.views import View
  3. from app01 import models
  4. from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
  5. # 自定义页码
  6. from utils.pager import Pageinfo
  7. def custom(request):
  8. # 1、首先查询所有的用户信息的数据总个数
  9. all_count=models.Userinfo.objects.all().count()
  10.  
  11. page_info = Pageinfo(request.GET.get('page'), all_count, 10, '/custom.html', 11)
  12. user_list = models.Userinfo.objects.all()[page_info.start():page_info.end()]
  13. return render(request,"custom.html",{"user_list":user_list,"page_info":page_info})

pager.py

  1. class Pageinfo(object):
  2. def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
  3. # current_page指的是当前页,all_count所有数据的总个数,per_page每一页有多少数据,base_url跳转的url,show_page=11每次共显示11个页码
  4. """
  5. 分页
  6. :param current_page: 指的是当前页
  7. :param all_count: 数据库总行数
  8. :param per_page: 每一页有多少数据
  9. :param base_url: 跳转的url
  10. :param show_page: 每次共显示11个页码
  11. """
  12. try:
  13. self.current_page=int(current_page)
  14. except Exception as e:
  15. self.current_page=1
  16. self.per_page=per_page
  17. a,b=divmod(all_count,per_page)#用数据库的总行数除以每一页有多少数据
  18. # 如果整除的话,即余数为0,则:
  19. if b:#如果b有值的话
  20. self.all_pager=a+1
  21. else:
  22. self.all_pager=a
  23.  
  24. self.show_page=show_page
  25. self.base_url=base_url
  26. def start(self):
  27. """
  28. 定义开始的行数,举例:如果点击的是第二页,(2-1)*10=10,是从第10条数据开始
  29. :return: 返回上一行结尾的数据
  30. """
  31. return (self.current_page-1)*self.per_page
  32.  
  33. def end(self):
  34. """
  35. 取的是结束的数据,用当前页乘以一页有10条数据
  36. 举例:如果点击的是第二页,2*10=20,是第20条数据结束
  37. :return:
  38. """
  39. return self.current_page*self.per_page
  40.  
  41. def pager(self):
  42. page_list=[]
  43. half=int((self.show_page-1)/2)
  44. # 如果总页数小于所应该展示的页数,例:如果总页数是5页,但是要求展示11条,总页数<11
  45. if self.all_pager<self.show_page:
  46. begin=1
  47. stop=self.all_pager+1#因为下面的for循环取值是左取右不取
  48.  
  49. else:# 当总页数大于11
  50. # 但是当点击的当前页<5的话,则应该显示1-11页
  51. if self.current_page<=half:
  52. begin=1
  53. stop=self.show_page+1
  54. else:#当点击的当前页大于5
  55. if self.all_pager-self.current_page<half:
  56. #当总页数减去点击的当前页<5的话,则应该显示后11条数据
  57. begin=self.all_pager-self.show_page+1
  58. stop=self.all_pager+1
  59. else:
  60. begin=self.current_page-half
  61. stop=self.current_page+half+1
  62. #再判断一些特殊情况
  63. if self.current_page<=1:
  64. prev = "<li><a href='#'>上一页</a></li>"#点击上一页不跳动,还是当前状态
  65. else:#否则跳转到上一页
  66. prev="<li><a href='%s?page=%s'>上一页</a></li>"% (self.base_url,self.current_page-1,)
  67.  
  68. page_list.append(prev)
  69.  
  70. for i in range(begin,stop):
  71. if i==self.current_page:
  72. # 如果点到当前页的话,则让点击的页码的颜色改变
  73. temp="<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
  74. else:
  75. temp = "<li><a href='%s?page=%s'>%s</a></li>" % (self.base_url, i, i,)
  76. page_list.append(temp)
  77.  
  78. if self.current_page>=self.all_pager:
  79. after="<li><a href='#'>下一页</a></li>"#点击下一页不跳动,还是当前状态
  80. else:#否则跳转到下一页
  81. after = "<li><a href='%s?page=%s'>下一页</a></li>" % (self.base_url, self.current_page + 1,)
  82. page_list.append(after)
  83.  
  84. return ''.join(page_list)

custom,html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
  7. </head>
  8. <body>
  9. <h1>用户列表</h1>
  10. <ul>
  11. {% for i in user_list %}
  12. <li>{{ i.username }}</li>
  13. {% endfor %}
  14. </ul>
  15.  
  16. <nav aria-label="Page navigation">
  17. <ul class="pagination">
  18. {{ page_info.pager|safe }}
  19. </ul>
  20. </nav>
  21. </body>
  22. </html>

最终的执行结果是:(页面展示)

 

django框架<二>的更多相关文章

  1. MVC其实很简单(Django框架)

    Django框架MVC其实很简单 让我们来研究一个简单的例子,通过该实例,你可以分辨出,通过Web框架来实现的功能与之前的方式有何不同. 下面就是通过使用Django来完成以上功能的例子: 首先,我们 ...

  2. Django框架-目录文件简介

    Rhel6.5 Django1.10 Python3.5 Django框架-目录文件简介 1.介绍Django Django:一个可以使Web开发工作愉快并且高效的Web开发框架. 使用Django, ...

  3. Django框架学习

    两个月前学习的Django框架,写了个简易婚恋调查网站,代码就懒得全贴了,有两张图记录下

  4. django框架的models

    在django的框架设计中采用了mtv模型,即Model,template,viewer Model相对于传统的三层或者mvc框架来说就相当对数据处理层,它主要负责与数据的交互,在使用django框架 ...

  5. Windows上python开发--2安装django框架

    Windows上python开发--2安装django框架 分类: 服务器后台开发2014-05-17 21:22 2310人阅读 评论(2) 收藏 举报 python django 上一篇文章中讲了 ...

  6. MySQL在Django框架下的基本操作(MySQL在Linux下配置)

    [原]本文根据实际操作主要介绍了Django框架下MySQL的一些常用操作,核心内容如下: ------------------------------------------------------ ...

  7. django框架介绍

    主要内容 1.        Django框架发展 2.        Django架构,MTV模式 3.        开发流程 4.        开发实例——Poll python下各种框架 一 ...

  8. Django学习(二) Django框架简单搭建

    为了快速学习Python进行Web的开发,所以我不准备从Python的基础学起,直接从Django框架入手,边学框架边学Python的基础知识. 下面就开始Django的快速开发之旅吧. 关于Djan ...

  9. Django - Django框架 简单介绍

    Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码 ...

  10. Django框架全面讲解

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

随机推荐

  1. vue render function

    vue render function https://vuejs.org/v2/guide/render-function.html { // Same API as `v-bind:class`, ...

  2. Java内存区域介绍

    Java虚拟机把内存划分成几个区域,每个区域都有各自的职责.下面将逐一分析每个区域. 有助于我们了解,每个方法,变量,对象等都去哪儿了! 程序计数器: 它占用一块很小的内存空间,可以看作是当前线程所执 ...

  3. wp如何代码重启手机

    用过windows phone手机操作系统的人都知道,wp的系统设置界面很长一串,我们并不能快速进入想要的设置项,更受不了的是有些常用的设置项竟然在最下边.因为前段时间没事做,于是乎写了个wp的工具类 ...

  4. C++解析(2):进化后的 const 分析

    0.目录 1.C语言中的const 2.C++中的const 3.对比 3.1 C语言与C++中的const 3.2 C++中的const与宏定义 4.小结 1.C语言中的const const修饰的 ...

  5. BZOJ3771 Triple 【NTT + 容斥】

    题目链接 BZOJ3771 题解 做水题放松一下 先构造\(A_i\)为\(x\)指数的生成函数\(A(x)\) 再构造\(2A_i\)为指数的生成函数\(B(x)\) 再构造\(3A_i\)为指数的 ...

  6. Linux之Makefile20160707

    说一下LINUX下的Makefile,直接根据实际碰到的Makefile进行解读: 当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile:M=$(PWD ...

  7. Java Socket TCP编程(Server端多线程处理)

    package com; import java.io.*; import java.net.Socket; /** * Socket Client * <p> * Created by ...

  8. 服务器上 tomcat 配置了 tomcat-users 但是还是 403 的问题

    默认情况下,tomcat 限制了只能本机访问 如果我们想要修改这个设置: 编辑 webapps/manager/META-INF/context.xml <!--<Valve classN ...

  9. jinja2 中的 Template 批量替换json字符串中的内容

    项目中用到elasticsearch,使用Json格式查询方式,一个查询语句中有好几个地方需要替换,且替换的值都相同.最开始把json转为字符串发方式,利用format函数处理,发现再转回json时无 ...

  10. windows下MySQL 5.7+ 解压缩版安装配置方法--转载

    方法来自伟大的互联网. 1.去官网下载https://dev.mysql.com/downloads/mysql/.zip格式的MySQL Server的压缩包,根据需要选择x86或x64版.注意:下 ...