How does Django handle foreignKeys internally? - python

I am curious how Django handles model relationships at the object level because I am working on building a custom json serializer, and I need to understand this so I have properly handle nested serialization. I am almost positive I will have to dive into some of the internals of python, but that will not be too big of a deal.

The field name in the model has _id appended to it in the table, and it stores the PK of the foreign model (as a FK normally would).
When the related field is accessed on a model, Django performs a query to retrieve the foreign model from the database.
When a model is assigned to the related field, Django reads the PK of the model and assigns it to the backing field in the table.

Related

Dynamically generate accompanying model in django

In my project i have many models in multiple apps, all of them inherit from one abstract model. I would like to create a model that would hold the changes to the history for every one of my models, so that every model would have its own history model. Each model would also have one-to-many relation to its history model. All history models would be the same, except for the foreign key to their respective model.
My problem is that I do not want to write all the history models manually. Instead i would like to have the history model created for every model automatically, so I don't have to write all that boilerplate code. Can this be achieved?
There is a widely-used django package that I believe solves this exact problem called django-reversion with a nice API. I recommend using it if it fits your needs rather than building a custom solution.
Object version control is usually better solved by serializing your objects and storing the serialization every time they are edited (e.g. in the json format).
You may also want to keep track of when objects are deleted.
This way, you only need to store a reference to the serialized object. Versions of all objects can live in the same database table and reference their "source" object using Django's generic relations.
You can eventually create your classes dynamically with type()
There is many ways to do it, but you can do something as follows:
class SomeParentClass: pass
NewClass = type('NewClass', (SomeParentClass,), {'new_method': lambda self:
'foo' } )
new_class_instance = NewClass()
print(new_class_instance.new_method())
So you can create models dynamically, with a different name, inherit from a different class, new methods...
You can then use globals()[variable_name_to_store_class] to assign newly created classes to a dynamic variable name.
Hope its relavant for your problem.

OneToManyField relationship in Django?

Is there a OneToManyField relationship in Django? There is a ManyToOneField relationship but that restrict you declare the relationship on the Many side.
You should recognise that Django fields represent database columns. A ForeignKey field is exactly that, a field on the model that represents a key in another model. But you can't model a "one-to-many" field in that way; what would the field on the model represent? So no, it is not possible.

Is it possible to use a table in the database when it is NOT a Django model?

Is it possible get a queryset from a table in the app database that is NOT a model in the app?
If I have a table that is not a model named "cartable", conceptually, I want to do this:
myqueryset = cartable.objects.all()
Is there a relatively easy way to do this? Thanks!
If you want to access an existing table in your database that is not managed by your application, you can still create a class for it, and tell django to ignore it for migrations.
Just create a model and add the fields you need to access and then add a meta class to tell django to leave it alone.
class MyModel(model.Model):
class Meta:
managed = False
you can read about that at https://docs.djangoproject.com/en/1.9/ref/models/options/#managed
To do so you would need to create a class (not a model), with methods that use raw SQL. You should see more details here on how to do so: https://docs.djangoproject.com/en/1.9/topics/db/sql/#executing-custom-sql-directly
Please note that you will have to manually create the object with the right properties afterwards.
If you wanted to use Django ORM without the models, I don't think it is possible. You could however create a model that matches your db in a separate app and never create migrations for it to ensure you don't accidentally modify the DB.
Short answer is, "not really". Django QuerySet deals with model instances, so everything in QuerySet API is tied into models. Everything expects to return model instances, uses model fields etc.
That said, you should be able to create a model for an existing table. You will need to add db_table to the Meta, so Django knows where the table lives. If you have some indexing, you will need to make sure Django's idea of indexes is the same as the one in the database. indexed=True on fields and unique_together in Meta should help a lot with that.

Simple REST API not based on a particular predefined model

Well, I do my first steps with Django and Django REST framework. The problem I face is that all examples throughout the whole Internet are based on hard-coded models. But the whole concept of models frustrates me a little bit, because I'm used to deal with different data which comes from numerous sources (various relational databases and nosql - all that stuff). So, I do not want to stick to a particular model with a fixed number of predefined fields, but I want to specify them just at the moment when a user goes to a particular page of my app.
Let's say I have a table or a collection in one of my databases, which stores information about users - it has any kinds of fields (not just email, name and likewise - all those fields as in all those examples throughout the web). So when a user goes to /users/ I connect to my datebase, get my table, set my cursor and populate my resultant dictionary with all rows and all fields I need. And REST API does all the rest.
So, I need a "first-step" example wich starts from data, not from a model: you have a table "items" in your favorite database, when a user goes to /items/, he or she gets all data from that table. To make such simplistic api, you should do this and this... I need this kind of example.
I think the key is to use the models differently. If you use onetomany or foreignkey references in your model construction you can more dynamically link different types of data together, then access that from the parent object.
For example, for your user, you could create a basic user model and reference that in many other models such as interests, occupation, and have those models store very dynamic data.
When you have the root user model object, you can access it's foreign key objects by either iterating through the dictionary of fields returned by the object or accessing the foreign key references directly with model.reference_set.all()

Django-Nonrel(mongo-backend):Model instance modification tracking

I am using Django non-rel version with mongodb backends. I am interested in tracking the changes that occur on model instances e.g if someone creates/edits or deletes a model instance. Backend db is mongo hence models have an associated "_id" fields with them in the respective collections/dbs.
Now i want to extract this "_id" field on which this modif operation took place. The idea is to write this "_id" field to another db so someone can pick it up from there and know what object was updated.
I thought about overriding the save() method from Django "models.Model" since all my models are derived from that. However the mongo "_id" field is obviously not present there since the mongo-insert has not taken place yet.
Is there any possibility of a pseudo post-save() method that can be called after the save operation has taken place into mongo? Can django/django-toolbox/pymongo provide such a combination?
After some deep digging into the Django Models i was able to solve the problem. The save() method inturn call the save_base() method. This method saves the returned results, ids in case of mongo, into self.id. This _id field can then be picked by by over riding the save() method for the model

Categories

Resources