django框架

182 阅读8分钟

Q查询进阶操作

from django.db.models import Q
q_obj = Q()   这里产生Q对象
q_obj.connector = 'or' 这里是默认多个条件的连接是and修改为or
q_obj.children.append(('pk',1)) 添加查询条件
q_obj.children.append(('price__gt',2000))  支持添加多个
res = models.Book.object.filter(q_obj)  查询支持直接填写q对象

ORM查询优化

  • ORM的查询默认都是惰性查询

  • ORM的查询自带分页处理

  • only与defer

      数据对象+含有指定字段对应的数据
      res = models.Book.object.only('title','price')
      print(res)   在这里打印输出后是queryset[数据对象、数据对象]
      for obj in res:
          print(obj.title) 点击括号内填写的字段  不走SQL查询
          print(obj.price)
          print(obj.publish_time)   可以点击括号内没有的字段获取数据  但是会走SQL查询
      
    
  • select_related与prefetch_related

           # res = models.Book.objects.all()
       for obj in res:
           print(obj.publish.name)   每次查询都需要走SQL
       res = models.Book.objects.select_related('authors')   先连表后查询封装
       res1 = models.Author.objects.select_related('author_detail')   括号内不支持多对多字段 其他两个都可以
       print(res1)
       for obj in res:
           print(obj.publish.name)   不再走SQL查询
    
      res = models.Book.objects.prefetch_related('publish')   子查询
      for obj in res:
          print(obj.publish.name)     
      
    

ORM事务操作

  • 1.事务的四大特性(ACID):原子性、一致性、隔离性、持久性

  • 2.相关SQL关键字

          start transaction;
          rollback;
          commit;
          savepoint;
    
  • 3.相关重要概念:脏读、幻读、不可重复读、MVCC多版本控制 django orm提供了至少三种开启事务的方式

    方式1:配置文件数据相关的添加键值对  这个全局有效
       'ATOMIC_REQUESTS':True每次请求所涉及到的orm操作同属于一个事务
    方式2:装饰器
        from django.db import transaction
        @transaction.atmic
        def index():pass
    方式3with上下文管理
       from django。db import transaction
        def reg():
          with transaction():pass
    

ORM常用字段类型

AutoField(Field)
- int自增列,必须填入参数 primary_key=True

BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True

注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models

class UserInfo(models.Model):
 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)

class Group(models.Model):
 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)

SmallIntegerField(IntegerField):
- 小整数 -3276832767

PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 032767
IntegerField(Field)
- 整数列(有符号的) -21474836482147483647

PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 02147483647

BigIntegerField(IntegerField):
- 长整型(有符号的) -92233720368547758089223372036854775807

BooleanField(Field)
- 布尔值类型

NullBooleanField(Field):
- 可以为空的布尔值

CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度

TextField(Field)
- 文本类型

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   上传图片的宽度保存的数据库字段名(字符串)

DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

DateField(DateTimeCheckMixin, Field)
- 日期格式      YYYY-MM-DD

TimeField(DateTimeCheckMixin, Field)
- 时间格式      HH:MM[:ss[.uuuuuu]]

DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

FloatField(Field)
- 浮点型

DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度

BinaryField(Field)
- 二进制类型
对应关系:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',

ORM常用字段参数

null:用于表示某个字段可以为空。

unique:如果设置为unique=True 则该字段在此表中必须是唯一的 。

db_index:如果db_index=True 则代表着为此字段设置索引。
default:为该字段设置默认值。

DateField和DateTimeField

auto_now_add

配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

 auto_now:配置上auto_now=True,每次更新数据记录的时候会更新该字段。
null                数据库中字段是否可以为空
db_column           数据库中字段的列名
db_tablespace
default             数据库中字段的默认值
primary_key         数据库中字段是否为主键
db_index            数据库中字段是否可以建立索引
unique              数据库中字段是否可以建立唯一索引
unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
unique_for_year     数据库中字段【年】部分是否可以建立唯一索引

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'), ]
                            )

to				关联表
to_field		关联字段(不写默认关联数据主键)
on_delete		当删除关联表中的数据时,当前表与其关联的行的行为。
         1、models.CASCADE
        级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除
    2、models.SET_NULL
        当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空
    3、models.PROTECT
        当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除
    4、models.SET_DEFAULT
        当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值
    5、models.SET()
        当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数
    6、models.DO_NOTHING
        什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似
        

Ajax

AJAX = 异步 JavaScript 和 XML。

AJAX 是一种用于创建快速动态网页的技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。

image.png

  • 基本语法

    $.ajax({
          url:'',  // 后端地址 三种填写方式 与form标签的action一致
          type:'post',  // 请求方式 默认也是get
          data:{'v1':v1Val, 'v2':v2Val},  // 发送的数据
          success:function (args) {  // 后端返回结果之后自动触发 args接收后端返回的数据
                   $('#d3').val(args)
                                  }
      })
      
      
    

Content-Type

1.urlencoded
        ajax默认的编码格式、form表单默认也是
        数据格式  xxx=yyy&uuu=ooo&aaa=kkk
        django后端会自动处理到request.POST中

2.formdata
        django后端针对普通的键值对还是处理到request.POST中 但是针对文件会处理到request.FILES中


3.application/json
        form表单不支持 ajax可以
        <script>
    $('#d1').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:JSON.stringify({'name':'jason','age':18}),  // 千万不要骗人家
            contentType:'application/json',
            success:function (args) {
                alert(args)
            }

        })
    })
</script>
        后端需要从request.body中获取并自己处理
        

Ajax携带文件数据

  • Ajax发送文件需要借助js内置对象FromData

      <body>
      <div class="row">
          <div class="col-md-8">
              用户名:<input type="text" name="username" id="name">
              密码:<input type="password" name="password" id="pwd">
              <input type="file" name="file" id="file">
              <button class="btn btn-success" id="d1">提交</button>
          </div>
      </div>
    
      <script>
          $('#d1').click(function () {
              // 1. 先产生一个FormData对象
              let fromData = new FormData();
              // 2. 添加普通键值对
              fromData.append('username', $('#name').val())
              fromData.append('password', $('#pwd').val())
              // 3. 添加文件对象
              fromData.append('file', $('#file')[0].files[0])
              console.log(111)
              // 4. 将对象通过ajax发送给后端
              $.ajax({
                  url: '',
                  type: 'post',
                  data: fromData,  //数据就是对象
                  contentType: false,  //不需要任何数据格式 Django后端会自动识别formData对象
                  processData: false,  //不对数据进行任何处理
                  success: function (args) {
    
                  }
    
    
              })
          })
      </script>
      </body>
    
      def ajax_file(request):
          if request.method == 'POST':
              print(request.POST)  # <QueryDict: {'username': ['17391767493'], 'password': ['111']}>
              print(request.FILES)
              # <MultiValueDict: {'file': [<InMemoryUploadedFile: 国庆作业安排.xls (application/vnd.ms-excel)>]}>
          return render(request, 'file.html')