Django deep serialization - follow reverse foreign key constraints - django

I have two models with a foreign key relationship:
class Company(models.Model):
field 1
field 2
class Employee(models.Model):
company = Model.ForeignKey('Company')
field 3
field 4
I would like to JSON serialize a company instance, and include all employees that have foreign-key relationships to it. IE, I'd like to create JSON that looks something like the following, in that it includes all fields for a company and all fields for all related employees.
[
{
"pk": 2,
"model": "app.company",
"fields": {
"field1": "value",
"field2": "value",
"employee": [
{
"pk": 19,
"model": "app.employee",
"fields": {
"field3": "value",
"field4": "value",
}
},
{
"pk": 25,
"model": "app.employee",
"fields": {
"field3": "value",
"field4": "value",
}
}
]
}
}
]
The Django serializer doesn't serialize relationships. Other questions here have asked how to deep serialize, but in the opposite direction -- IE, serialize an employee along with its related company. Answers to these questions have pointed out that the wadofstuff django-full-serializer plugin allows you to do this kind of deep serialization. The problem is that the wadofstuff plugin only follows these relationships unidirectionally -- it won't follow a reverse foreign key constraint. So, I'm trying to roll my own here. Any suggestions on how to accomplish this?

So, here's a super budget way of doing this which works for my purposes, but I feel like there has to be a better way (including it here in case others are looking for how to do this). It works for me only because I'm sending just one Company object at a time, and as such the fact that it doesn't explicitly preserve the relationship hierarchy isn't a big deal.
Given Company instance of "company":
companyJSON = serializers.serialize('json', [company, ])
employeeJSON = serializers.serialize('json', company.employee_set.all())
fullJSON = companyJSON[:-1] + ", " + employeeJSON[1:]

Related

Django id vs pk in fixtures/loaddata

A strange (to the uninitiated lol) issue with models using a custom CharField for a primary key/id:
id = models.CharField(max_length=10, primary_key=True)
Feeling I know what I'm doing, I've created the following (json) fixtures file:
[
{
"model": "products.product",
"id": "am11",
"fields": {
"title": "Test Product A",
}
},
{
"model": "products.product",
"id": "am22",
"fields": {
"title": "Test Product B",
}
}
]
, and proceeded with loading it:
✗ python manage.py loaddata fixtures/products.json
Installed 2 object(s) from 1 fixture(s)
Well, it kinda lied. A check on the admin page or in a shell shows that there's only one Product in the database - the last one in the fixture's list. Curiously enough, attempts to delete this Product via the admin page silently fail, only via the shell can it actually be deleted. Further investigation (in the shell) revealed an interesting problem - that (single) Product created has pk/id set to an empty string(?!..but explains why admin fails to delete it). If I manually create another, either on admin page or in the shell, the new product appears without any issues, both id and pk set to the string given. But loaddata with fixture fails on this. Originally discovered this problem when a basic test failed - given the same fixture, in failed the assertion on the number of products in the queryset, claiming there's just one.
Now, I was able to "fix" the problem by renaming 'id' to 'pk' in the fixture file. I say 'fix', because I don't understand what bit me here. Any clue will be appreciated. Thanks!

Using hasMany relation and cascading ORM level in loopback4

I have created 2 models Author and Books where Author has hasMany relation with Book and Book has belongsTo relation with author.
While saving data using ORM models the cascading is not happening i.e
{
"authorId": 1,
"name": "qwery",
"experience": 2,
"books": [{
"BookId": 12,
"category": "string"
}]
}
The above should create a Author record in Author table and create a Book record with the authorId in Book table, which is not happening whereas from belongsTo it can able to create an Author record with just authorId.
You can find the code in the following GIT
You need to create a AuthorBookController to connect the two. Please see example code in here: https://github.com/strongloop/loopback-next/blob/master/examples/todo-list/src/controllers/todo-list-todo.controller.ts

Associating multiple items with a single REST call

I am using the Loopback framework, and have modelA which is in a many-to-many relation with modelB.
I want to know if it's possible to relate multiple items from modelB to modelA.
There is currently a way to relate one item with this call:
/modelA/{id}/modelB/rel/{fk}
Is there any way to perform this in a bulk operation?
If I understand your question correctly, I think you can simply do it through a filter. ModelA has many modelBs, Let me assume the relation name is 'modelBs'
modelA.find({
where: [your filter option on model A]
include: {
relation: 'modelBs',
scope: {
[your filters on model B]
}
}
})
in restful way:
/modelAs?filter[include]=modelBs&filter[where]....
The official documentation may help: https://docs.strongloop.com/display/public/LB/Querying+data
It seems to be HasManyThrough model.
I believe your model names starts with lowercase but ideally it should be ModelA and ModelB and their instances can then be saved in modelA and modelB variables.
In order to use add method, you will need to first find instance of ModelA first using ModelA.findById which you can save in modelA variable and then use the following code:
modelA.modelBs.add(modelBFieldsObject, function(err, patient) {
...
});
where modelBs should be the name of relation in the ModalA.json file as in
"relations": {
"modelBs": {
"type": "hasMany",
"model": "ModelB",
"foreignKey": "modelAId",
"through": "ModelAModelB",
"keyThrough": "modelBId"
}
...
I think it should be allowed to pass an array of modelBFieldsObject to create multiple instances as in
modelA.modelBs.add([modelBFieldsObject, modelBFieldsObject], function(err, patient) {
...
});
Tip: For clarity, name your models beginning with upper case letter and their instance variable in camelCase format.
References: Methods added to the model.

Django Union Query

I need to develop a UNION query in Django with 3 models namely WebQuery,WebReply and BusinessOwners and the output should be of the form below.
{
"(#conversation_id#)_(#b_id#)": {
"from": "(#user_id)",
"email": "(#user_email)",
"date_time": "#get from db",
"query": "are you open ?",
"from_r_id": "(#representative_id)",
"from_r_name": "(#rep_name)",
"business_registered": "FALSE"
"to_business_name": "CCD saket",
"chat": [{
"direction": 1,
"text": "yes sir",
"date_time": "424 577"
}, {
"direction": 0,
"text": "ok",
"date_time": "424 577"
}]
},
I know how to query when only one model is involved, but not sure of the union query.
How will this be achieved?
I personally would say that if this is going to be a common query then I would recommend making a SQL View then querying that.
w3schools has a VERY simple overview of what a view is : http://www.w3schools.com/sql/sql_view.asp
In SQL, a view is a virtual table based on the result-set of an SQL statement.
This means you can write your required sql statement and create a view using this. Then create a django model which mirrors that view which you can then use to query.
So, you will create an SQL view:
CREATE VIEW view_name AS
SELECT a, b, c
FROM table_name
WHERE condition
Then create a django model, which has a slight difference to a normal model:
class view_name(models.Model):
class Meta:
# https://docs.djangoproject.com/en/1.5/ref/models/options/#django.db.models.Options.managed
managed = False
a = models.CharField(max_length)
....
managed = false > https://docs.djangoproject.com/en/1.5/ref/models/options/#django.db.models.Options.managed
You can then query this using the normal django orm syntax
Or there is similar questions:
Previous stackoverflow question, union in django orm
How can I find the union of two Django querysets?
How can I find the union of two Django querysets? provides an example of a union using the '|' operator. I'm not sure how different your models are. If there's common fields you could place those in a separate model and use model inheritance

Django - Serializing model with additional data

I am trying to serialize some model data along with some extra information like so:
data = {
'model_data': serializers.serialize('json', SomeModel._default_manager.all(), fields=('name','last_updated')),
'urls': {
'updateURL':'http://www.bbc.co.uk',
},
}
json = simplejson.dumps(data)
It seams my 'model_data' object is being serialized twice as it seems to be returned as a string and not a valid json object:
Object
model_data: "[{"pk": 1, "model": "models.SomeModel", "fields": {"last_updated": null, "name": "Name test"}}]"
urls: Object
What am I doing wrong here?
How about having the value of the model_data field be handled again by another JSON processor? I think it will be the same, since the JSON processor always expects a string that is always in the correct format.