最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django分頁(yè)查詢(xún)并返回jsons數(shù)據(jù)(中文亂碼解決方法)

 更新時(shí)間:2018年08月02日 08:31:22   作者:SharpCJ  
這篇文章主要介紹了Django分頁(yè)查詢(xún)并返回jsons數(shù)據(jù)(中文亂碼解決方法),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

一、引子

Django 分頁(yè)查詢(xún)并返回 json ,需要將返回的 queryset 序列化, demo 如下:

# coding=UTF-8

import os

from django.core import serializers
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render
from django.http import HttpResponse
from mypage.models import Product


# Create your views here.


def getAllProducts(request):
  products_list = Product.objects.all()
  paginator = Paginator(products_list, 10) # Show 10 products per page
  page = request.GET.get('page', 0)
  try:
    products = paginator.page(page)
  except PageNotAnInteger:
    # If page is not an integer, deliver first page.
    products = paginator.page(10)
  except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.
    products = paginator.page(paginator.num_pages)

  json_data = serializers.serialize("json", products, ensure_ascii=False)
  return HttpResponse(json_data, content_type='application/json; charset=utf-8')

很容易出現(xiàn)的一個(gè)錯(cuò)誤是中文亂碼,重點(diǎn)在于 json_data = serializers.serialize("json", products, ensure_ascii=False) 中第三個(gè)參數(shù)。

二、Serialize----序列化django對(duì)象

官方文檔原文: https://docs.djangoproject.com/en/2.1/topics/serialization/

django的序列化框架提供了一個(gè)把django對(duì)象轉(zhuǎn)換成其他格式的機(jī)制,通常這些其他的格式都是基于文本的并且用于通過(guò)一個(gè)管道發(fā)送django對(duì)象,但一個(gè)序列器是可能處理任何一個(gè)格式的(基于文本或者不是)

django的序列化類(lèi)位于django.core下面的serializers文件夾里面,base.py文件里面定義了序列器和反序列器的基類(lèi)以及一些異常, init .py文件定義了如何根據(jù)格式來(lái)選擇對(duì)應(yīng)的序列器等內(nèi)容,我們一起來(lái)看看吧

init.py和base.py文件的函數(shù)原型如下圖

def serialize(format, queryset, **options):
"""Serialize a queryset (or any iterator that returns database objects) using
a certain serializer."""
s = get_serializer(format)()
s.serialize(queryset, **options)
return s.getvalue()
class Serializer(object):
  """  Abstract serializer base class.  """
  # Indicates if the implemented serializer is only available for
  # internal Django use.
  internal_use_only = False
  def serialize(self, queryset, **options):

那下面我們開(kāi)始正式講解django的序列化操作了

序列化數(shù)據(jù)

在最高層的api,序列化數(shù)據(jù)是非常容易的操作,看上面的函數(shù)可知,serialize函數(shù)接受一個(gè)格式和queryset,返回序列化后的數(shù)據(jù):

簡(jiǎn)單的寫(xiě)法:

from django.core import serializers
data = serializers.serialize("xml", SomeModel.objects.all())

復(fù)雜的寫(xiě)法:

XMLSerializer = serializers.get_serializer("xml")
xml_serializer = XMLSerializer()
xml_serializer.serialize(queryset)
data = xml_serializer.getvalue()

反序列化數(shù)據(jù)

一樣的簡(jiǎn)單,接受一個(gè)格式和一個(gè)數(shù)據(jù)流,返回一個(gè)迭代器

for obj in serializers.deserialize("xml", data):
  do_something_with(obj)

然而,deserialize返回的的是不是簡(jiǎn)單的django類(lèi)型對(duì)象,而是DeserializedObject實(shí)例,并且這些實(shí)例是沒(méi)有保存的,請(qǐng)使用DeserializedObject.save()方法把這些數(shù)據(jù)保存到數(shù)據(jù)庫(kù)

序列化格式

django之處很多的序列化格式,有些需要你安裝第三方支持的模塊,xml,json和yaml是默認(rèn)支持的

注意事項(xiàng)

如果你是使用utf-8或者其他的非ascii編碼數(shù)據(jù),然后用json序列器,注意穿一個(gè)ensure_ascii參數(shù)進(jìn)去,否則輸出的編碼將會(huì)不正常

json_serializer = serializers.get_serializer("json")()
json_serializer.serialize(queryset, ensure_ascii=False, stream=response)

序列化參數(shù)

序列化的是是可以接受額外的參數(shù)的,總共有三個(gè)參數(shù),如下:

self.stream = options.pop("stream", StringIO())
    self.selected_fields = options.pop("fields", None)
    self.use_natural_keys = options.pop("use_natural_keys", False)

stream

將序列化后的數(shù)據(jù)輸出到該stream流中,接上面的復(fù)雜的寫(xiě)法:

out = open("file.xml", "w")
xml_serializer.serialize(SomeModel.objects.all(), stream=out)

selected_field

選擇序列化的屬性,通過(guò)制定fields參數(shù),fields是一個(gè)元組參數(shù),元素是選擇要序列化的屬性

from django.core import serializers
data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))

use_natural_keys

是否使用自然的關(guān)鍵字,默認(rèn)是false(即是使用主鍵)

默認(rèn)的外鍵和多對(duì)多關(guān)系序列化策略是使用主鍵,一般情況下是很好地,但有些情況下就不是這樣了。比如外鍵到ContentType的時(shí)候,由于ContentType是django的數(shù)據(jù)庫(kù)進(jìn)程同步的時(shí)候自動(dòng)產(chǎn)生的,它們的關(guān)鍵字不是那么容易去預(yù)測(cè)的。

一個(gè)整數(shù)id也不總是最方便的索引到一個(gè)對(duì)象的方法,所以基于這些情況,django提供了use_natural_keys這個(gè)參數(shù),

一個(gè)natural key是一個(gè)可以不使用主鍵就可以用來(lái)區(qū)分一個(gè)元素的屬性組合的元組

natural keys的反序列化

考慮這兩個(gè)模型

from django.db import models
class Person(models.Model):
  first_name = models.CharField(max_length=100)
  last_name = models.CharField(max_length=100)
  birthdate = models.DateField()
  class Meta:
    unique_together = (('first_name', 'last_name'),)
class Book(models.Model):
  name = models.CharField(max_length=100)
  author = models.ForeignKey(Person)

默認(rèn)Book 的序列化數(shù)據(jù)將會(huì)使用一個(gè)整數(shù)索引到一個(gè)作者,例如,用json的是,一個(gè)Book的序列化數(shù)據(jù)大概是這樣的,42是外鍵Author的主鍵

{
  "pk": 1,
  "model": "store.book",
  "fields": {
    "name": "Mostly Harmless",
    "author": 42
  }
}

但這不是一個(gè)很好的方法,不是嗎?你需要知道這個(gè)主鍵代表到底是哪個(gè)Author,并且要求這個(gè)主鍵是穩(wěn)定和可預(yù)測(cè)的。所以,我們可以增加一個(gè)natural key的處理函數(shù),請(qǐng)?jiān)趯?duì)應(yīng)模型的管理模型里面定義一個(gè)get_by_natural_key方法,例如:

from django.db import models
class PersonManager(models.Manager):
  def get_by_natural_key(self, first_name, last_name):
    return self.get(first_name=first_name, last_name=last_name)
class Person(models.Model):
  objects = PersonManager()
  first_name = models.CharField(max_length=100)
  last_name = models.CharField(max_length=100)
  birthdate = models.DateField()
  class Meta:
    unique_together = (('first_name', 'last_name'),)

這樣之后,序列化的結(jié)果大概是這樣的:

{
  "pk": 1,
  "model": "store.book",
  "fields": {
    "name": "Mostly Harmless",
    "author": ["Douglas", "Adams"]
  }
}

natural keys的序列化

如果你想在序列化的時(shí)候使用natural key,那你必須在被序列化的模型里面頂一個(gè)natural_key方法,并在序列化的時(shí)候使用use_natural_keys=True屬性如下:

class Person(models.Model):
  objects = PersonManager()
  first_name = models.CharField(max_length=100)
  last_name = models.CharField(max_length=100)
  birthdate = models.DateField()
  def natural_key(self):
    return (self.first_name, self.last_name)
  class Meta:
    unique_together = (('first_name', 'last_name'),)

serializers.serialize('json', [book1, book2], use_natural_keys=True)

注意:natural_key()和get_by_natural_key()不是同時(shí)定義的,如果你只想重載natural keys的能力,那么你不必定義natural_key()方法;同樣,如果你只想在序列化的時(shí)候輸出這些natural keys,那么你不必定義get_by_natural_key()方法

序列化過(guò)程中的依賴(lài)關(guān)系

因?yàn)閚atural keys依賴(lài)數(shù)據(jù)庫(kù)查詢(xún)來(lái)解析引用,所以在數(shù)據(jù)被引用之前必須確保數(shù)據(jù)是存在的。看下面的例子,如果一個(gè)Book的natural key是書(shū)名和作者的組合,你可以這樣寫(xiě):

class Book(models.Model):
  name = models.CharField(max_length=100)
  author = models.ForeignKey(Person)

  def natural_key(self):
    return (self.name,) + self.author.natural_key()

那么問(wèn)題來(lái)了,如果Author還沒(méi)有被序列化呢?很明顯,Author應(yīng)該在Book之前被序列化,為此,我們可以添加一個(gè)依賴(lài)關(guān)系如下:

def natural_key(self):
  return (self.name,) + self.author.natural_key()
natural_key.dependencies = ['example_app.person']

這保證了Person對(duì)象是在Book對(duì)象之前被序列化的,同樣,任何一個(gè)引用Book的對(duì)象只有在Person和Book對(duì)象都被序列化之后才會(huì)被序列化

繼承的模型

如果是使用抽象繼承的時(shí)候,不必在意這個(gè)問(wèn)題;如果你使用的是多表繼承,那么注意了:必須序列化所有的基類(lèi),例如:

class Place(models.Model):
  name = models.CharField(max_length=50)
class Restaurant(Place):
  serves_hot_dogs = models.BooleanField()

如果僅僅序列化Restaurant模型,那么只會(huì)得到一個(gè)serves_hot_dog屬性,基類(lèi)的屬性將被忽略,你必須同時(shí)序列化所有的繼承的模型,如下:

all_objects = list(Restaurant.objects.all()) + list(Place.objects.all())
data = serializers.serialize('xml', all_objects)

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 簡(jiǎn)單示例入門(mén)了解WxPython教程

    簡(jiǎn)單示例入門(mén)了解WxPython教程

    這篇文章主要通過(guò)演示簡(jiǎn)單示例帶大家入門(mén)了解WxPython,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Python簡(jiǎn)單進(jìn)程鎖代碼實(shí)例

    Python簡(jiǎn)單進(jìn)程鎖代碼實(shí)例

    這篇文章主要介紹了Python簡(jiǎn)單進(jìn)程鎖代碼實(shí)例,本文講解了線程和進(jìn)程的相關(guān)知識(shí),然后給出了Python的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04
  • pandas中.loc和.iloc以及.at和.iat的區(qū)別說(shuō)明

    pandas中.loc和.iloc以及.at和.iat的區(qū)別說(shuō)明

    這篇文章主要介紹了pandas中.loc和.iloc以及.at和.iat的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • pytorch實(shí)現(xiàn)從本地加載 .pth 格式模型

    pytorch實(shí)現(xiàn)從本地加載 .pth 格式模型

    今天小編就為大家分享一篇pytorch實(shí)現(xiàn)從本地加載 .pth 格式模型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • 破解安裝Pycharm的方法

    破解安裝Pycharm的方法

    今天小編就為大家分享一篇關(guān)于破解安裝Pycharm的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • Python中參數(shù)打包和解包的實(shí)現(xiàn)

    Python中參數(shù)打包和解包的實(shí)現(xiàn)

    在Python中,打包和解包參數(shù)是一種操作方式,可以將多個(gè)參數(shù)打包成一個(gè)元組或字典,也可以將一個(gè)元組或字典解包成多個(gè)參數(shù),本文就來(lái)介紹一下如何使用
    2023-09-09
  • 用表格幫你了解Python數(shù)據(jù)類(lèi)型

    用表格幫你了解Python數(shù)據(jù)類(lèi)型

    這篇文章主要為大家介紹了Python數(shù)據(jù)類(lèi)型,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助<BR>
    2022-01-01
  • Python 人工智能老照片修復(fù)算法學(xué)習(xí)

    Python 人工智能老照片修復(fù)算法學(xué)習(xí)

    老舊或者破損的照片如何修復(fù)呢?本文主要介紹了一個(gè)非常不錯(cuò)的照片恢復(fù)開(kāi)源項(xiàng)目:Bringing-Old-Photos-Back-to-Life。感興趣的小伙伴快來(lái)看看呀
    2021-11-11
  • python如何發(fā)送帶有附件、正文為HTML的郵件

    python如何發(fā)送帶有附件、正文為HTML的郵件

    這篇文章主要介紹了python如何發(fā)送帶有附件、正文為HTML的郵件,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • Python中變量交換的例子

    Python中變量交換的例子

    這篇文章主要介紹了Python中變量交換的例子,Python中的變量交換不需要臨時(shí)變量,一個(gè)等號(hào)即可實(shí)現(xiàn)變量的交換,非常方便,需要的朋友可以參考下
    2014-08-08

最新評(píng)論

科技| 武山县| 东平县| 沂南县| 和龙市| 阳山县| 宁河县| 弥渡县| 罗城| 汾阳市| 阿巴嘎旗| 东辽县| 饶阳县| 会东县| 拜城县| 宁津县| 尼勒克县| 威信县| 临颍县| 石首市| 黎川县| 彰武县| 安龙县| 鄂托克前旗| 赤城县| 宜宾市| 颍上县| 璧山县| 藁城市| 原阳县| 台江县| 井陉县| 祁门县| 武冈市| 西林县| 伊春市| 监利县| 广河县| 岚皋县| 阜新| 临城县|