I don't know is this a right platform to ask this question or not. I recently came across Django rest framework. I am using django for one of my projects.I want to use DRF as an api client for my project. I came across this term serializing the model instances and serializers. I went through DRF Tutorial , but I still have no idea of how it actually works.My questions are :
1.Why are serializers used? What purpose they serve?
2.What more can be done using serializers?
3.How do serializers work?
There may be lots of references on this present in the internet but I want a simple and easy-to-understand answer to this. Thanks!!
1.Why are serializers used? What purpose they serve?
In a very general way:
Imagine you want to invite your friend for a coffee. To inform your friend, you text "what: coffee, time: 12h, where: The fancy coffee bar on the corner". This text is your serialization of your idea.
The DRF does this for your Django models.
Imagine you have a JS client that doesn't (want to) know about your DB or Django models. You serialize your Django objects into JSON to have that data available in a JS compatible way:
data = {
"address": {
"street": "Fancy Street 1b"
}
};
DRF offers an easy way to translate Django model instances into JSON (or other formats). And that is what serializers do. They also offer to deserialize what your JS frontend sends back to your server.
2.What more can be done using serializers?
You can add more fields that are computed at serialization time. For example, instead of adding simple IDs for related objects you can also serialize the related objects and add them nested into the JSON (or XML or whatever format).
You can also add fields that you only need on the frontend side for some view, like things related to paging etc.
3.How do serializers work?
For python, the simplest serializer from python to JSON would be one that takes a python dictionary and simply creates string keys from the python keys, translates Django boolean into true and false strings, python None into null etc.
For more complex translations, you might want to add your own logic. E.g. like resolving related object references on Django models. Or formatting date objects into ISO standard strings (with timezone), localizing (decimal) numbers, localizing texts in general etc.
Related
I am currently trying to connect my new Django rest API to my already existing mongodb database. Currently I am trying to copy the structure of my database objects as models. I ran into the problem, that I set up a structure like this in my db:
{
objects: { DE: [], US: [] }
}
The attributes DE and US can be anything here (Any geo for that matter). Is there any way I can incorporate this kind of pattern in my djongo model?
If by anything, you truly mean anything (or at least more than a few types of data), you could set up the model(s) as follows:
from djongo import models
...
ObjectDataModel(models.Model):
US = models.ListField()
DE = models.ListField()
class Meta:
abstract = True # Stops a database table from being made
...
YourModel(models.Model):
objects = models.ArrayModelField(model_container=ObjectDataModel)
You could also add custom validation if you want the ListFields to not just take anything under the sun; here's how to do that.
NOTE: This makes the objects field completely inaccessible via the Django Admin website; this is simply because the Admin site cannot possibly represent all possible input types that a ListField might be able to handle for the user (you can still submit values to the field via your forms/views, however).
You can also design a custom field, if you have the time to do so. I am (sadly) not terribly familiar with the geo field, so I'll instead point you here for instructions on how to go about that. You might also want to look at how Djongo's author went about implementing the ListField mentioned prior; it might give a hint on how to make list-like database entries. Here's the raw code for that.
Hope this helps!
We are developing a document management system. The user approaches our system and creates his own document. So, there is a need to implement custom fields i.e, user-defined-fields. Basically, each document has different fields with different datatypes.
Is using JSON Field in mysql the best way to implement this? If so, how? Else, what would you suggest?
I am looking for performance.
I've written a json-schema to validate the json that comes with the POST request to my API. No I need to deserialize this json.
When I started builing the nested serializers structure I noticed that the process is very similar. So my question is: can my already written json-schema help with deserilization process?
[UPDATE] The blog post I linked below is quite outdated. Instead, I've gone and implemented a modern example of using JSONSchema validation and DRF together which you can see on this answer here.
Before I stumbled across your question I found this article which demonstrates how (and potentially when) to use a JSONSchema with Django REST Framework.
Django Rest Framework integrates well with models to provide out of the box validation, and ModelSerializers allow futher fine-grained custom validation. However, if you’re not using a model as the resource of your endpoint then the code required for custom validation of complex data structure can get hairy.
If there is a heavily nested data structure then a serializer can be used that has a nested serializer, which also has a nested serializer, and so on – or a JSON schema and custom JSON parser can be employed.
Using a JSON schema generation tool also provides a quick win: generate the canonical “pattern” of valid JSON structure using data known to be of the correct structure. This post will go through doing this JSON schema validation using Django Rest Framework.
I'd like to know where to put code that doesn't belong to a view, I mean, the logic.
I've been reading a few similar posts, but couldn't arrive to a conclusion.
What I could understand is:
A View is like a controller, and lot of logic should not put in the controller.
Models should not have a lot of logic either.
So where is all the logic based stuff supposed to be?
I'm coming from Groovy/Grails and for example if we need to access the DB or if we have a complex logic, we use services, and then those services are injected into the controllers.
Is it a good practice to have .py files containing things other than Views and Models in Django?
PS: I've read that some people use a services.py, but then other people say this is a bad practice, so I'm a little confused...
I don't know why you say
we can't put a lot of logic in the controller, and we cannot have the models with a lot of logic either
You can certainly put logic in either of those places. It depends to a great extent what that logic is: if it's specifically related to a single model class, it should go in the model. If however it's more related to a specific page, it can go in a view.
Alternatively, if it's more general logic that's used in multiple views, you could put it in a separate utility module. Or, you could use class-based views with a superclass that defines the logic, and subclasses which inherit from it.
Having a java background I can relate with this question.
I have been working on python for quite some time. Even though I do my best to treat Java as Java and Python as Python, some times I mix them both so that I can get a good deal out of both.
In short
Put all model related stuff in models app, it could be from simply models definition to custom save , pre save hooks .....
Put any request/ response related stuff in views, and some logic like verifying Jon schema, validation request body ... handling exceptions and so on ....
Put your business logic in separate folder/ app or module per views directory/ app. Meaning have separate middle module between your models and views.
There isn't strict rule to organise your code as long as you are consistent.
Project : Ci
Models: ci/model/device.py
Views: ci/views/list_device.py
Business logic:
(1) ci/business_logic/discover_device.py
Or
(2) ci/views/discover_device.py
Short answer: Django is more of a MTV or MVT (Model / Template / View), as described in the official FAQ : https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names
The business logic has its place in your views, but nothing prevents you from putting it inside a "utils.py", "services.py" or anything to your liking.
If the functionality fits well as a method of some model instance, put it there. After all, models are just classes.
Otherwise, just write a Python module (some .py file) and put the code there, just like in any other Python library.
Don't put it in the views. Views should be the only part of your code that is aware of HTTP, and they should stay as small as possible.
I'm working on a Django-based web service and I'm trying to figure out what the best way to do my serialization will be.
The tricky requirement, though, is that I'd like to have pretty much full control over format of, and fields contained in, the response.
For example, the Django serializers (which, unfortunately, includes the wadofstuff serializer) automatically wrap the fields in { model: "app.Model", pk: 42, fields: { ... }}, which is great for creating fixtures, but isn't great for me — I'd like full control over the output.
Additionally, I'd like a serializer that is aware of Django's objects so, for example, it will do the Right Thing with a QuerySet or ManyToManyField.
Currently I'm thinking of using django-piston's emitters.py, but my experience with django-piston has only been mediocreª, so I'd like to see if there are other options.
So, are there any other options for customizable Django serializers?
ª: It's sparsely documented and tested, and I've had some problems with the serializer.
Have you looked at django-piston? It should have a bunch of stuff to make this easier.
(Not sure about serialization specifically, but Django RESTy web services.)
When I need some custom serialization really fast and my case doesn't require deserialization I just write django template that can make any format I want from list/queryset/object. You can then call render_to_string with proper context and you have your data serialized.
UPDATE: some short example
Let's say you want to get json format accepted by datatables.net plugin. Since there are some special parameters required serializing queryset using simplejson or sth else is impossible here (or might be not so easy at least). We found that fastest way to provide such structure is to create simple template like this one:
{
"sEcho": {{sEcho}},
"iTotalRecords": {{iTotalRecords}},
"iTotalDisplayRecords": {{iTotalDisplayRecords}},
"aaData":[
{% for obj in querySet %}
[
"{{obj.name}}",
"{{obj.message|truncatewords:20}}",
"{{obj.name}}"
]
{% if not forloop.last %}
,
{% endif %}
{% endfor %}
]
}
which renders to beatiful json that we were looking for. It gives you full control over the format also. Other advantages is the abillity to modify objects fields by using built-in django filters which in our case was really usefull.
I know this is not serialization as described in books but if f you want to convert some object to a custom format this solution might be the fastest one. For some reason django developers allowed to render template to any given format not only html, so why not to use it?
Example shown above is very specific but you can generate any other format. Of course writing deserializer for that could restore object from this format might be painfull but if you don't need it...
EDIT :
Now out at https://bitbucket.org/sebpiq/any2any/
I am currently writing a full-featured serialization framework for Django. The aim is precisely to have full control over the serialization. It would probably fill-in your requirements pretty well ! However, it is not ready yet. I estimate that in 1 or 2 weeks I will be able to release a first version.
You can still check the google code : http://code.google.com/p/django-serializable/ , even give some help if you are interested in it.
There will be a featured download when the first release will be out !