Django Models: Where is Model class? - python

On documentation it has been said that each model is a python subclass of models.Model class that is inside django folder followed by db folder. When i look inside my django folder i see a db folder which was expected and inside my db folder i see models folder which contains lot of files. But I was expecting a models.py package which contains Model class. So my doubt is from where does this models.Model class come from?
This might be not a top level question but I am hopeful someone here will certainly help.

Nope it's not magic it's django , it does exist if you go to the django's source code, you can see that the Model class exists, But in that way don't you had to import models in this way??:
from django.db.models.base import Model
Yes you can do it in that way, But django does it for you in the models/__init__ file, so the only thing you have to do is:
from django.db import models
models refers to the models folder inside django.db but when you import it, it brings you all the things that are inse the models/____init__.py file, I recommend you to read this

Related

Django: How does it find the User model?

I have a question to the AUTH_USER_MODEL in Django:
https://docs.djangoproject.com/en/dev/ref/settings/#auth-user-model
The default value is auth.User. However, the actual model is in auth.models.User. How does Django find the correct class?
I am asking because when I usually use models in Django, I have to write from myapp.models import MyModel. So, why do I not need models in auth.User for AUTH_USER_MODEL?
Can some explain me that or show the code that uses it?
Well you define models in the models.py file of an app. So that means that the module in which you stored the model class is app.models. Therefore the import reads:
from app.models import MyModel
Django has in essence nothing to do with this: this is how Python loads modules and classes from these module(s).
Django however loads - when you for example run the server - the apps that are located in the INSTALLED_APPS list of the settings file (usually settings.py), and thus constructs a "register" where it stores Django models, and it names them in a uniform way: app_name.ModelName. There is no reason to specify models here, since models are defined in models.py, and it thus would only introduce "noise".
You can obtain a reference to the model class with apps.get_model [Django-doc]
from django.apps import apps
apps.get_model('app_name', 'ModelName')
It thus then checks the registers of the loaded models, and returns a reference to the model.
Linking through a string is useful (and sometimes required) when there is cyclic referencing. For example if you have two models A and B, and A refers to BandBthroughA(for example withForeignKeys), then one of the two models is defined first. This means that if you defineAfirst, it can not refer to theB` class itself, since at that point it does not yet exists. In Django, one then specifies the model through a string. The Django system will then first load the models, and then "tie the knot": resolve the references by replacing the strings with a reference to the actual model class.

Where do Django model fields reside?

I've looked into the source code for some django model fields, in this case DateTimeField. In the tutorial for Django, we are taught to create a DateTimeField like this:
from django.db import models
field = models.DateTimeField()
But looking in the source code, the file where DateTimeField is defined is django/db/models/fields. So, intuitively, if I were to import the field, I would write from django.db.models.fields import DateTimeField.
Do you see the difference? In the tutorial, they import it from django/db/models, while it looks like from the location of the source code that it actually resides in django/db/models/fields. Why doesn't the tutorial way of importing DateTimeField crash?
The fields are imported in django/db/models/__init__.py
Take a look at the source code.
Possibly relevant: What is init.py for?

Django get list of Classes defined in controller of an application

I am creating django permissions based on django views rather than basic model based permissions. Hence I want to get the list of all the classes in a view. I tried the following:
from django.apps import apps
apps.get_app_config('my_app')
And also:
import sys, inspect
inspect.getmembers(sys.modules['my_app'], inspect.isclass)
But I didn't get classes object.
apps.get_app_config('my_app').get_models()
will return a list of all models declared in your application.
if you want to get all models including those in INSTALLED_APPS you can
appconfigs=apps.get_app_configs()
for appconfig in appconfigs:
models = appconfig.get_models()

Create Models in other than models.py files (Django-Wiki)

I am using Django wiki module in my project , IN wiki module models are created in their different files.Structure are as follows.
models/
article.py
abcd.py
...
__init.py__
Now I want to add some new models into article.py but after creating models when I try to migrate them I am getting the message , Nothing seems to change. However If I change any field of existing model then migration catch the change.
My init.py files imports all models of articles.py , So I think migration must have created the models but It doesn't . so can anyone tell me where I am wrong.
Thanks

Django model proxy in diffrent package

I want to use one model for global scope for app. In future, probably models will be changed. I created backend.py file in root directory of project with model wrapper (I think it's the best solution as I can change declaration of models in one place, and using global model is more transparent than using imports from app).
from project.backend import models as backend_models
class Game(backend_models.Game):
class Meta:
proxy = True
But when I make any relation to model I get following error:
screens.screen: 'game' has a relation with model <class 'energy.backend.Game'>, which has either not been installed or is abstract.
If I import project.package.Game, not backend.Game everything works fine. Of course I have project.backend in installed apps. Only I don't know how to point django that class in backend is installed, and loaded model (from other app).
EDIT
I solved it by in backend.py:
Game = em_models.Game
But there must be same solution with extending model in non-models package.

Categories