Django paging Query and return jsons data, Chinese garbled solution

Source: Internet
Author: User

Django paging Query and return jsons data, Chinese garbled solution

First, the Primer

The Django paging query and returns JSON, need to serialize the returned Queryset, the demo is as follows:

  # coding=utf-8import osfrom django.core import serializersfrom django.core.paginator import Paginator, Pagenotaninteger, emptypagefrom django.shortcuts import renderfrom django.http import Httpresponsefrom mypage.models Import product# Create your views here.def getallproducts (Request): Products_list = Product.objects.all () paginator = Paginator (Products_list, ten) # Show ten products per page page = Request. Get.get (' page ', 0) try:products = paginator.page (page) except Pagenotaninteger: # If page is not a I        Nteger, deliver first page. Products = Paginator.page (ten) except Emptypage: # If page is out of range (e.g. 9999), deliver last page of ResU        Lts. 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 ')  

A bug that is easy to come up with is Chinese garbled, with the emphasis on json_data = serializers.serialize("json", products, ensure_ascii=False) the third parameter.

Ii. Serialize----Serializing Django objects

Official Document Original: https://docs.djangoproject.com/en/2.1/topics/serialization/

The Django Serialization framework provides a mechanism for converting Django objects into other formats, usually in the form of text-based and used to send Django objects through a pipeline, but a sequencer can handle any one format (text-based or not)

The Django serialization class is located in the serializers folder below Django.core, and the base.py file defines the base class for the sequencer and the deserializer as well as some exceptions,init. The py file defines how to select the corresponding sequencer based on the format, so let's take a look at it.

The function prototypes for the init. Py and base.py files are as follows

def serialize(format, queryset, **options):"""Serialize a queryset (or any iterator that returns database objects) usinga 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):

Well, let's start by formally explaining the Django serialization operation.

Serialization of data

At the top of the API, serializing the data is very easy to manipulate, see above function, serialize function accepts a format and Queryset, returns the serialized data:

A simple notation:

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

A complex notation:

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

As simple as accepting a format and a stream of data, returning an iterator

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

However, the deserialize return is not a simple Django type object, but a Deserializedobject instance, and these instances are not saved, use Deserializedobject.save () method to save the data to the database

Serialization format

Django has a lot of serialization formats, some require you to install third-party supported modules, Xml,json and YAML are supported by default

Precautions
If you are using Utf-8 or other non-ASCII encoded data, then use the JSON sequencer, pay attention to wearing a ensure_ascii parameter, otherwise the output encoding will not be normal

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

The serialization is acceptable for additional parameters, with a total of three parameters, as follows:

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

Output the serialized data to the stream stream, followed by the complex notation above:

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

Select the serialized attribute, by setting the fields parameter, fields is a tuple parameter, and the element is the attribute to select to serialize

from django.core import serializersdata = serializers.serialize(‘xml‘, SomeModel.objects.all(), fields=(‘name‘,‘size‘))
Use_natural_keys

Whether to use natural keywords, the default is False (that is, using the primary key)

The default foreign key and many-to-many relationship serialization policy is to use a primary key, which is generally good, but in some cases it is not. For example, when the foreign key to ContentType, because the ContentType is the Django database process synchronization automatically generated, their keywords are not so easy to predict.

An integer ID is also not always the most convenient way to index an object, so based on these conditions, Django provides the Use_natural_keys parameter,

A natural key is a tuple that can be used to distinguish an attribute combination of an element without using a primary key

Deserialization of the natural keys

Consider these two models

from django.db import modelsclass 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)

The serialized data of the default book will be indexed to an author using an integer, for example, in JSON, the serialized data of a book is like this, 42 is the primary key of the foreign key author

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

But that's not a good way to do it, is it? You need to know which author the primary key represents, and require that the primary key be stable and predictable. So, we can add a natural key handler function, define a Get_by_natural_key method in the corresponding model's management model, for example:

from django.db import modelsclass 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‘),)

After that, the result of the serialization is presumably this:

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

If you want to use natural key when serializing, you must top a Natural_key method in the serialized model and use the Use_natural_keys=true attribute when serializing it as follows:

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)
Note: Natural_key () and Get_by_natural_key () are not defined at the same time, and if you only want to reload natural keys, then you do not have to define the Natural_key () method; If you only want to output these natural keys when serializing, then you don't have to define the Get_by_natural_key () method

Dependencies in the serialization process

Because natural keys relies on database queries to parse references, you must ensure that the data exists before the data is referenced. Look at the following example, if a book's natural key is a combination of the title and the author, you can write:

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()

So the question is, what if author hasn't been serialized yet? Obviously, author should be serialized before the book, so we can add a dependency as follows:

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

This ensures that the person object is serialized before the book object, and that any object that references book will be serialized only after the person and book object are serialized

The inherited model

If you are using abstract inheritance, do not care about this problem; If you are using multiple table inheritance, note that all base classes must be serialized, for example:

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

If you only serialize the restaurant model, you will only get a Serves_hot_dog property, the properties of the base class will be ignored, and you must serialize all the inherited models at once, as follows:

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

Django paging Query and return jsons data, Chinese garbled solution

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.