Django回顾5

目录

一.多表查询

1.基于对象的跨表查询

一对多查询(publish与book)

一对一查询(Author与AuthorDetail)

多对多查询(Author与Book)

2.基于双下划线的跨表查询

一对多查询

多对多查询

一对一查询

连续跨表查询

3.聚合查询与分组查询

聚合查询

aggregate(*args,**kwargs)

分组查询

annotate()

4.F查询与Q查询

F查询:拿到某个字段在表中具体的值

Q查询:为了组装成与、或、非 条件

二.其他字段和字段参数

1.ORM字段

2.ORM字段参数

3.关系字段

三.Django与Ajax

1.什么是Ajax

2.基于jquery的Ajax实现

3.案例

(1)通过Ajax实现前端输入两个数字,服务器做加法返回到前端页面

(2)基于Ajax进行登录验证

4.文件上传

请求头ContentType

(1)application/x-www-form-urlencoded

(2)multipart/form-data

(3)application/json

基于Form表单上传文件:

视图函数:

5.基于Ajax上传文件

6.Ajax提交json格式数据

7.Django内置的serializers(把对象序列化成json字符串)


一.多表查询

1.基于对象的跨表查询

一对多查询(publish与book)

正向查询(按字段:publish)

# 查询主键为1的书籍的出版社所在的城市
book_obj=Book.objects.filter(pk=1).first()
# book_obj.publish 是主键为1的书籍对象关联的出版社对象
print(book_obj.publish.city)

反向查询(按表名:book_set)

publish=Publish.objects.get(name="苹果出版社")
#publish.book_set.all() : 与苹果出版社关联的所有书籍对象集合
book_list=publish.book_set.all()    
for book_obj in book_list:
       print(book_obj.title)
# 一对多正向查询
 book=Book.objects.filter(name='红楼梦').first()
 print(book.publish)#与这本书关联的出版社对象
 print(book.publish.name)
 # 一对多反向查询
 # 人民出版社出版过的书籍名称
 pub=Publish.objects.filter(name='人民出版社').first()
 ret=pub.book_set.all()
 print(ret)

一对一查询(Author与AuthorDetail)

正向查询(按字段:authorDetail):

justin=Author.objects.filter(name="justin").first()
print(justin.authorDetail.telephone)

反向查询(按表名:author):

# 查询所有住址在北京的作者的姓名
 
authorDetail_list=AuthorDetail.objects.filter(addr="beijing")
for obj in authorDetail_list:
     print(obj.author.name)
# 一对一正向查询
# lqz的手机号
lqz=Author.objects.filter(name='lqz').first()
tel=lqz.author_detail.telephone
print(tel)
# 一对一反向查询
# 地址在北京的作者姓名
author_detail=AuthorDatail.objects.filter(addr='北京').first()
name=author_detail.author.name
print(name)

多对多查询(Author与Book)

正向查询(按字段:authors):

# 眉所有作者的名字以及手机号
 
book_obj=Book.objects.filter(title="眉").first()
authors=book_obj.authors.all()
for author_obj in authors:
     print(author_obj.name,author_obj.authorDetail.telephone)

反向查询(按表名:book_set):

# 查询justin出过的所有书籍的名字
  author_obj=Author.objects.get(name="justin")
  book_list=author_obj.book_set.all()        #与justin作者相关的所有书籍
  for book_obj in book_list:
    print(book_obj.title)
# 正向查询----查询红楼梦所有作者名称
book=Book.objects.filter(name='红楼梦').first()
ret=book.authors.all()
print(ret)
for auth in ret:
print(auth.name)
# 反向查询 查询lqz这个作者写的所有书
author=Author.objects.filter(name='lqz').first()
ret=author.book_set.all()
print(ret)

2.基于双下划线的跨表查询

Django还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认SQL JOIN联系,要做跨关系查询,就使用两个下划线来链接模型(model)间字段的名称,直到最终连接到你想要的model为止

正向查询按字段,反向查询按表名小写来告诉ORM引擎join哪张表

一对多查询

# 练习:  查询苹果出版社出版过的所有书籍的名字与价格(一对多)

# 正向查询 按字段:publish

queryResult=Book.objects.filter(publish__name="苹果出版社").values_list("title","price")

# 反向查询 按表名:book
queryResult=Publish.objects.filter(name="苹果出版社").values_list("book__title","book__price")
查询的本质一样,就是select from的表不一样
# 正向查询按字段,反向查询按表名小写
# 查询红楼梦这本书出版社的名字
# select * from app01_book inner join app01_publish
# on app01_book.publish_id=app01_publish.nid
ret=Book.objects.filter(name='红楼梦').values('publish__name')
print(ret)
ret=Publish.objects.filter(book__name='红楼梦').values('name')
print(ret)

多对多查询

# 练习: 查询lqz出过的所有书籍的名字(多对多)

# 正向查询 按字段:authors:
queryResult=Book.objects.filter(authors__name="lqz").values_list("title")

# 反向查询 按表名:book
queryResult=Author.objects.filter(name="lqz").values_list("book__title","book__price")
# 正向查询按字段,反向查询按表名小写
# 查询红楼梦这本书出版社的名字
# select * from app01_book inner join app01_publish
# on app01_book.publish_id=app01_publish.nid
ret=Book.objects.filter(name='红楼梦').values('publish__name')
print(ret)
ret=Publish.objects.filter(book__name='红楼梦').values('name')
print(ret)
# sql 语句就是from的表不一样
# -------多对多正向查询
# 查询红楼梦所有的作者
ret=Book.objects.filter(name='红楼梦').values('authors__name')
print(ret)
# ---多对多反向查询
ret=Author.objects.filter(book__name='红楼梦').values('name')
ret=Author.objects.filter(book__name='红楼梦').values('name','author_detail__addr')
print(ret)

一对一查询

# 查询lqz的手机号

# 正向查询
ret=Author.objects.filter(name="lqz").values("authordetail__telephone")

# 反向查询
ret=AuthorDetail.objects.filter(author__name="lqz").values("telephone")
# 查询lqz的手机号
# 正向查
ret=Author.objects.filter(name='lqz').values('author_detail__telephone')
print(ret)
# 反向查
ret= AuthorDatail.objects.filter(author__name='lqz').values('telephone')
print(ret)

连续跨表查询

# 练习: 查询人民出版社出版过的所有书籍的名字以及作者的姓名

# 正向查询
queryResult=Book.objects.filter(publish__name="人民出版社").values_list("title","authors__name")
# 反向查询
queryResult=Publish.objects.filter(name="人民出版社").values_list("book__title","book__authors__age","book__authors__name")


# 练习: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称

# 方式1:
queryResult=Book.objects.filter(authors__authorDetail__telephone__regex="151").values_list("title","publish__name")
# 方式2:    
ret=Author.objects.filter(authordetail__telephone__startswith="151").values("book__title","book__publish__name")
# ----进阶练习,连续跨表
# 查询手机号以33开头的作者出版过的书籍名称以及书籍出版社名称
# author_datail author book publish
# 基于authorDatail表

ret=AuthorDatail.objects.filter(telephone__startswith='33').values('author__book__name','author__book__publish__name')
print(ret)

# 基于Author表
 ret=Author.objects.filter(author_detail__telephone__startswith=33).values('book__name','book__publish__name')
print(ret)

# 基于Book表
ret=Book.objects.filter(authors__author_detail__telephone__startswith='33').values('name','publish__name')
print(ret)

# 基于Publish表  
ret=Publish.objects.filter(book__authors__author_detail__telephone__startswith='33').values('book__name','name')
    print(ret)

3.聚合查询与分组查询

聚合查询

aggregate(*args,**kwargs)
# 计算所有图书的平均价格
from django.db.models import Avg
Book.objects.all().aggregate(Avg('price'))
#{'price__avg': 34.35}

aggregate()是QuerySet的一个终止子句,意思是说它返回一个包含一些键值对的字典,键的名称是聚合值的标识符,值是计算出来的聚合值,键的名字是按照字段和聚合函数的名称自动生成出来的,如果你想要为聚合值指定一个名称,可以向聚合子句提供它

Book.objects.aggregate(average_price=Avg('price'))
#{'average_price': 34.35}

如果你希望生成不止一个聚合,可以向aggregate()子句中添加另一个参数

# 如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
from django.db.models import Avg, Max, Min
Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
#{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
# 查询所有书籍的平均价格
from django.db.models import Avg,Count,Max,Min
ret=Book.objects.all().aggregate(Avg('price'))
# {'price__avg': 202.896}
# 可以改名字
ret=Book.objects.all().aggregate(avg_price=Avg('price'))
# 统计平均价格和最大价格
ret=Book.objects.all().aggregate(avg_price=Avg('price'),max_price=Max('price'))
# 统计最小价格
ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price'))
# 统计个数和平均价格
ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('price'))
ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('nid'))
print(ret)

分组查询

annotate()

annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)

总结:跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询

# 统计每本书的作者个数
from django.db.models import Avg, Max, Sum, Min, Max, Count
book_list = models.Book.objects.all().annotate(author_num=Count("authors"))
for book in book_list:
     print(book.name)
     print(book.author_num)
book_list = models.Book.objects.all().annotate(author_num=Count("authors")).values('name','author_num')
print(book_list)




# 统计每一个出版社的最便宜的书
publishList=Publish.objects.annotate(MinPrice=Min("book__price"))
for publish_obj in publishList:
    print(publish_obj.name,publish_obj.MinPrice)




# 统计每一本以py开头的书籍的作者个数:
queryResult=Book.objects.filter(title__startswith="Py").annotate(num_authors=Count('authors'))




# 统计不止一个作者的图书(作者数量大于1):
ret=models.Book.objects.annotate(author_num=Count("authors")).filter(author_num__gt=1).values('name','author_num')
print(ret)

4.F查询与Q查询

F查询:拿到某个字段在表中具体的值

在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较,如果我们对两个字段的值做比较就要用到Django提供的F(),F()的实例可以在查询中引用字段来比较同一个model实例中两个不同字段的值

# 查询评论数大于收藏数的书籍
from django.db.models import F
Book.objects.filter(commnetNum__lt=F('keepNum'))

Django支持F()对象之间以及F()对象和常数之间的加减乘除和取模的操作

# 查询评论数大于收藏数2倍的书籍
Book.objects.filter(commnetNum__lt=F('keepNum')*2)

修改操作也可以使用F函数,比如将每一本书的价格提高30元

Book.objects.all().update(price=F("price")+30)

Q查询:为了组装成与、或、非 条件

filter()等方法中的关键字参数查询都是一起进行‘and’的,如果你需要执行更复杂的查询(例如or语句),可以使用Q对象

from django.db.models import Q
Q(title__startswith='Py')

Q对象可以使用&和|操作符组合起来当一个操作符在两个Q对象上使用时会产生一个新的Q对象

bookList=Book.objects.filter(Q(authors__name="XXX")|Q(authors__name="justin"))


# 等同于:
    WHERE name ="XXX" OR name ="justin"

二.其他字段和字段参数

1.ORM字段

  • AutoField
    • int自增列,必须填入参数primary_key=True,当model中如果没有自增列,则会自动创建一个名为id的列
  • IntegerField
    • 一个整数类型,范围在-2147483648 to 2147483647
  • CharField
    • 日期字段,日期格式YYYY-MM-DD,相当于Python中的datetime.date()实例
  • DateField
    • 日期字段,日期格式YYYY-MM-DD,相当于Python中的datetime.date()实例
  • DateTimeField
    • 日期时间字段,格式YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
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):
- 小整数 -32768 ~ 32767

PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647

PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647

BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

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

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

3.关系字段

  • ForeignKey
    • 外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 ‘一对多’中’多’的一方
    • ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系
  • to
    • 设置要关联的表
  • to_field
    • 设置要关联的表的字段
  • related_name
    • 反向操作时,使用的字段名,用于代替原反向查询时的’表名_set’
  • related_query_name
    • 反向查询操作时,使用的连接前缀,用于替换表名
  • on_delete
    • 当删除关联表中的数据时,当前表与其关联的行的行为
      • models.CASCADE:删除关联数据,与之关联的也删除
      • models.DO_NOTHING:删除关联数据,引起错误LntegrityError
      • models.PROTECT:删除关联数据,引起ProtectedError
      • models.SET_NULL:删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
      • models.SET_DEFAULT:删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
      • models.SET:删除关联数据
        • 1.与之关联的值设置为指定值,设置:models.SET(值)
        • 2.与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

三.Django与Ajax

1.什么是Ajax

Ajax(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)

  • 同步交互:客户端发出一个请求后,等待服务器响应结束后才能发出第二个请求
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束就可以发出第二个请求

Ajax除了异步的特点还有局部刷新(在不知不觉中完成请求和响应过程)

优点: 

  1. Ajax使用Javascript技术向服务器发送异步请求
  2. Ajax无须刷新整个页面

2.基于jquery的Ajax实现



3.案例

(1)通过Ajax实现前端输入两个数字,服务器做加法返回到前端页面

def test_ajax(requests):
    n1=int(requests.POST.get('n1'))
    n2=int(requests.POST.get('n2'))
    return HttpResponse(n1+n2)
$("#submit").click(function () {
    $.ajax({
        url: '/test_ajax/',
        type: 'post',
        data: {
            n1: $("#num1").val(),
            n2: $("#num2").val()
        },
        success: function (data) {
            console.log(data)
            $("#sum").val(data)
        },

    })
})
+=

(2)基于Ajax进行登录验证

用户在表单输入用户名和密码,通过Ajax提交给服务器,服务器验证后返回响应信息,客户端通过响应信息确定是否登录成功,成功则跳转首页,失败则在页面显示相应的报错信息

def auth(request):
    back_dic={'user':None,'message':None}
    name=request.POST.get('user')
    password=request.POST.get('password')
    print(name)
    print(password)
    user=models.user.objects.filter(name=name,password=password).first()
    print(user)
    # print(user.query)
    if user:
        back_dic['user']=user.name
        back_dic['message']='成功'
    else:
        back_dic['message']='用户名或密码错误'
    import json
    return HttpResponse(json.dumps(back_dic))
$("#submit3").click(function () {
        $.ajax({
            url: '/auth/',
            type: 'post',
            data: {
                'user': $("#id_name").val(),
                'password': $('#id_password').val()
            },

            success: function (data) {
                {#console.log(data)#}
                var data=JSON.parse(data)
                if (data.user){
                    location.href='https://www.baidu.com'
                }else {
                    $(".error").html(data.message).css({'color':'red','margin-left':'20px'})
                }
            }


        })
    }
)

traditional:true(可以序列化一层列表,多层不行,要转JSON格式上传)

4.文件上传

请求头ContentType

(1)application/x-www-form-urlencoded

这是最常见的POST提交数据的方式,浏览器的原生表单,如果不设置enctype属性,那么最终就会以application/x-www-form-urlencoded方式提交数据

(2)multipart/form-data

也是常见的POST数据提交的方式,我们使用表单上传文件时,必须让表单的enctype等于multipart/form-data

(3)application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

基于Form表单上传文件:
用户名: 头像:

必须指定enctype='multipart/form-data'

视图函数:
def file_put(request):
    if request.method=='GET':
        return render(request,'file_put.html')
    else:
        # print(request.POST)
        # print(request.POST)
        print(request.body)  # 原始的请求体数据 
        print(request.GET)  # GET请求数据 
        print(request.POST)  # POST请求数据 
        print(request.FILES)  # 上传的文件数据
        # print(request.body.decode('utf-8'))
        print(request.body.decode('utf-8'))

        print(request.FILES)
        file_obj=request.FILES.get('avatar')
        print(type(file_obj))
        with open(file_obj.name,'wb') as f:
            for line in file_obj:
                f.write(line)
        return HttpResponse('ok')

5.基于Ajax上传文件

$("#ajax_button").click(function () {
    var formdata=new FormData()
    formdata.append('name',$("#id_name2").val())
    formdata.append('avatar',$("#avatar2")[0].files[0])
    $.ajax({
        url:'',
        type:'post',
        processData:false, //告诉jQuery不要去处理发送的数据
        contentType:false,// 告诉jQuery不要去设置Content-Type请求头
        data:formdata,
        success:function (data) {
            console.log(data)

        }

    })
})

6.Ajax提交json格式数据

$("#ajax_test").click(function () {
    var dic={'name':'lqz','age':18}
    $.ajax({
        url:'',
        type:'post',
        contentType:'application/json',  //一定要指定格式 contentType: 'application/json;charset=utf-8',
        data:JSON.stringify(dic),    //转换成json字符串格式
        success:function (data) {
            console.log(data)
        }

    })

})

提交到服务器的数据都在request.body里,取出来自行处理

7.Django内置的serializers(把对象序列化成json字符串)

from django.core import serializers
from django.core import serializers
def test(request):
    book_list = Book.objects.all()    
    ret = serializers.serialize("json", book_list)
    return HttpResponse(ret)

你可能感兴趣的:(django,数据库,python)