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.
Related
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.
I've enjoyed using Django quite a bit over the years. Right now I'm working for a company that is building some shared internal libraries for accessing information from our databases. Right now things are terribly sloppy - lots of inline SQL code. Some colleagues were working on doing some accessing code, and it occurred to me that this is the sort of thing that I'm used to Django doing out of the box. I had also heard that Django is fundamentally modular, so that I could just use the ORM system in isolation. I know there are other packages for this like SqlAlchemy, but I also hear that Django does things easier for the average case, which is likely all we'll need. I also know Django, and don't know SQLAlchemy.
So, I can do a proof of concept, like the following. Here is the directory structure:
+-- example.py
+-- transfer
| +-- __init__.py
| +-- models.py
Here is models.py
import django.conf
import django.db.models
django.conf.settings.configure(
DATABASES = ..., # database info
INSTALLED_APPS = ("transfer",),
SECRET_KEY = 'not telling',
)
django.setup()
class TransferItem(django.db.models.Model)
# model info here
example.py
from transfer.models import TransferItem
items = TransferItem.objects.all()
print items
This seems to work fine, as far as it goes. But I'm worried about the bootstrap code in a library context. Specifically:
Is there danger in django thinking of this as an app? In this case, "transfer" is a root module, but in a library context this could be buried deep. For example, "mycompany.data.protocols.transfer". Theoretically, we could have these data models defined throughout the codebase. How can this "app list" scale?
The call to setup really worries me. The django docs specifically say only to call setup once. And yet the nature of a library is that any python application could import whatever type of data model they want. I can't make any assumptions about which django "apps" they might want, or what order they want it in. Would if one type of model is used, data is returned, and only then does the python application decide it needs to import another type of model (quite possibly in a different "app")?
So, the fundamental question is this:
Is there a good way to use django ORM in a python library?
EDIT: This is not a duplicate of the CLI tool question. I know how to run django outside the web server. I even gave code samples showing this. I want to know if there's a way to run django where I don't have "apps" per se - where model files could be imported by client code and used in any order.
OK, here's my own attempt to answer the question after some research.
I can create a baseclass for my models anywhere in the library as follows:
from django.db import models
from django.apps import apps
import django.conf
django.conf_settings.configure(
DATABASES = ...
)
apps.populate((__name__,))
class LibModel(models.Model):
class Meta:
abstract = True
app_label = __name__
Then anywhere in the library I can create my own models with this baseclass. Since I'm not relying on the "app" for the database names, I need to state them explicitly.
class SpecificModel(LibModel):
# fields go here
class Meta(LibModel.Meta):
db_table = "specific_model_table_name"
This gets around my concern of having to simulate the structure of an "app". The name property in the base class supplies Django with all it needs, and then Django quits whining about not finding an app. The other model files can live wherever they want.
However, there is still a big concern I have which might be lethal. Django's initialization itself is still singleton in nature. If my library were itself imported by a Django application, it would all crash and burn. I've asked for solutions to this in this follow up question.
i'm happy with django built in user/auth , i just want to add some fields to it and change table name (mostly the last one , i can use another table for custom fields )
so i searched around and apparently we can use subclass as suggested on Rename Django's auth_user table?
So i have to start a new app and use it's model to as a subclass for AbstractUser or there is another way? (After all i just want to use it's model and other parts of app are useless )
anyway i created a new project / started app called customuser and in its model i have this code
customuser/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class customuser(AbstractUser):
class Meta:
swappable = 'AUTH_USER_MODEL'
db_table = 'customuser'
i ran makemigrations AND migrate ... it's done successfully
but atill the tables with default name was created in database as you can see below ... am i missing something ?
To use a custom user model, you need to set the AUTH_USER_MODEL setting in your settings module.
Note that you don't need to set swappable = 'AUTH_USER_MODEL'. This is an undocumented and private attribute, and is probably better left untouched.
Quite frankly if you're still in the position to do it, i'd just start a new app. It says in the docs that this decision is best made before starting your project because its a pain in the ... its hard.
If you intend to set AUTH_USER_MODEL, you should set it before creating any migrations or running manage.py migrate for the first time.
The solution otherwise is to dumpdata from the database, and manually tweak it so any reference to the user class in your dump file is replaced with your new user class. then you need to create some migrations to change the schema.
So it is doable. its just much simpler to start from a fresh project.
Django allows you to override the default User model by providing a value for the AUTH_USER_MODEL setting that references a custom model
AUTH_USER_MODEL = 'myapp.MyUser'
This dotted pair describes the name of the Django app (which must be in your INSTALLED_APPS), and the name of the Django model that you wish to use as your user model.
A full example of an admin-compliant custom user app can be found on the Django Project website.
I am new to odoo. My requirement is to add few custom models to odoo and communicate to those models through odoo api. I want through multiple tutorials for how to create new model in odoo.
Followed link (https://www.odoo.com/documentation/8.0/howtos/backend.html) to create new module and create new model in it. I am able to create module named 'openacademy' as suggested and also I am able to see on the odoo UI.
Following is the model I have created.
from openerp import models, fields
class LessMinimalModel(models.Model):
_name = 'test.model2'
name = fields.Char()
But when I am trying webservice from my Django project with the object name 'test.model2', it is giving error "Object test.model2 doesn't exist".
Am I missing something here? Is there something needs to be configured to access through API ?
Edit:
I have installed the module and model is also getting shown under Database Structure - > Models as shown below.
You need to restart server and update your module.
Before that your py files must be added in __init__.py.
Go to Settings -> Update Module List
Then Settings -> Installed Modules remove filtration and search your module and install it.
Once your module installed your model will be created.
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