Django with multiple Apps and reusing the same database tables - python

I am quite new to Django. Right now I am working on a prototype with ~30 database tables. I have understood that with Django you preferably want to have quite small Apps, with limited number of Models.
I want to use the same Models (i.e. database tables) in several different Apps. What is the best practice to achieve this? I am using mysql.

might be quite late for your question.
You may use same model by different app just by refering to it.
First your apps should be under the same project.
Choose one app as 'core' and define your models under it,(I have read that models are better to be at app level)
Then whenever you would like to use a model from that app, import that app's model at the beginning of the code.
Let say we have two apps: app_1 and app_2
and a model defined under app_1/models.py: model_1
In app_2/views.py , import model_1
from app_1.models import model_1

Related

When to make a django app, rather than just a model

Recently I've been making a few test projects in Django and while I've found the structure to be better than that of other Web Frameworks, I am a little confused on the concept of different 'apps'.
Here is a test case example:
Suppose I have a simple CRUD application where users post a picture and a title, with a small description, but I want other users to have the ability to create a review of this picture.
Seeing as both the "Post" and "Review" models in this case require CRUD functionality, would I just have two models in the same app, and associate them with one another? Or have two separate apps with different urls.py and views.py files?
I have a hunch I've been doing it wrong and it should be just two models, if this is the case how would I go about writing the urls and views for two models in the same app?
Thanks and any input is appreciated!
The term application describes a Python package that provides some
set of features. Applications may be reused in various projects.
So in this case, better to have both Post and Review as two models in one app, since both of them apply to pictures.
how would I go about writing the urls and views for two models in the same app
The Django project provides a near perfect documentation on how to structure urls and views.
In your case, I think the better is to put your two models in one app.

Does Django's singleton architecture make it unworkable as a standalone ORM in a library?

I like the Django ORM. It's simple, easy to use, and reasonably powerful.
I'm currently developing some internal sites for the VFX company I work for, for which I've used Django. In the meantime, we are developing other python applications and libraries to be used in various contexts in production. There's a number of places in which our core library needs to be interacting with some databases, and using an ORM like Django would really help things. I'm aware of other options like SqlAlchemy or PeeWee, but I'd like to see if Django will work since I use it on the websites and I like its API better.
Using Django as an ORM in a library is tricky (as I explored in a previous question), because Django expects to be used as a website with "apps". In a library, I might want to define any number of data models, which would exist in appropriate places in the library but not inside any Django app (as we're not using any other parts of the framework). So far so good.
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 a glaring use case where this all falls apart. Say that my Django web application wants to use some functionality from the company core python library, which now uses the Django ORM for various things. Since I make a call to django.conf.settings.configure in the library, Django is going to scream about defining the settings more than once when it tries to run the main application.
So basically, a library using the Django ORM is incompatible with Django. Wonderful.
Is there any way around this? I mean, it's a lovely ORM - is it really this impossible to use in a standalone modular way? Is the Django architecture utterly singleton in nature, making this impossible?
*Not a duplicate
I'm trying to have a company python library that uses Django as an ORM. Some of the things that could depend on it might be Django websites themselves. How do I get around Django's singleton insistence on only setting the settings config once? Or is it possible? None of these answers address this!
You can check if django has already been configured.
from django.apps import apps
from django.conf import settings
if not apps.ready:
settings.configure()
django.setup()
When starting Django application - core python library can be configured as separate app an be loaded on startup.
Also, check this answer on dynamic app loading at runtime.
A simple answer is how to initialize Django in a standalone application and do it compatible with Django applications.
import os
import django
if not 'DJANGO_SETTINGS_MODULE' in os.environ:
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysettings'
# # or without DJANGO_SETTINGS_MODULE directly
# from django.conf import settings
# settings.configure(DATABASES=... other...)
django.setup()
# this shouldn't be before DJANGO_SETTINGS_MODULE or settings.configure(...)
from myapp.models import MyModel
# this shouldn't be called before django.setup()
queryset = MyModel.objects.filter(...)
This is more compatible with Django then the answer by Oleg Russkin (where a risk of cyclic dependency at django.setup() is possible if the code is called inside inside a setup() initiated by another similar code or a normal Django project started by manage. It is similar to manage.py where django.setup() is also called internally by execute_from_command_line(sys.argv). The setup initializes all modules related to INSTALLED_APPS all urls modules and consequently all views etc. Many of them are lazy, but still. If any code called by setup() depends on this then neither the condition not apps.ready doesn't help. The setup() is not reentrant and the startup fails.)
Much more general answer
An important concept of Django is to support writing reusable parts of code ("applications" in Django terminology, that can be developed and tested independently. There can be also a tree of dependencies, but uncontrolled mutual dependencies should be avoided if possible) Reusable applications are expected that they can be easier combined to whole project ("project" in Django terminology is with all settings necessary to run it by Python.)
The only unavoidable and useful "singleton" in Django ORM are database connections django.db.connections and django.conf.settings especially INSTALLED_APPS. Only one connection should be used to the same database from the same process or thread.
Django is very configurable. An extreme example: It is possible to write a single file project where all code like settings, models, URL configs and views is defined in one file. That extreme that is probably useful only for some special tests or very short demos or as an exercise. It is even possible to define a project by one file with two "reusable" applications :-)
Django supports also "legacy databases" where the database structure is shared with existing non Django applications and models can be created by inspectdb command. Table names in such models are explicit and don't contain the app name. On the other hand the app name prefix is useful to prevent a possible conflict of the same table names from independent "applications". An important decision is if you can use it as a "legacy" database or a normal Django database.
You can decide between following two solutions or to combine them:
Use e.g. foo_models or bar.models and import all models from them e.g. to app.models and add only that "app" to INSTALLED_APPLICATIONS. This can be viable if it is only for one company and never otherwise and central name assigment is possible. (easiest but little naive)
Use some coarse separation of namespaces to several apps. You should probably use not more than one app with simple names without app name prefix.
Think ahead about migrations**. They will be probably very complicated and very soon impossible if you will create later more projects for the same database and different subsets of database tables without separating them to more apps and without app namespace.
There is really no "singleton" in Django ORM except of django.db.connections itself. If you use more databases you can direct some tables to a specific database by DATABASE_ROUTERS, even with two different models that use the same table name without a prefix.

Use different models to read data from different databases in django

I need a way of reading data in django from different DBs using different models, because models and fields in the db have changed between the projects.
What I try to do is this:
from sbo.core import models as sbo_core_models
from sbo_cloud.core import models as cloud_core_models
company_details = sbo_core_models.CompanyDetails.objects.using('sbo').filter(company=sbo_company).order_by("id")[0]
new_company_details = cloud_core_models.CompanyDetails.objects.get(id=int(reply['id']))
the model that actually gets used for the new_company_details is actually sbo_core_models.CompanyDetails and not cloud_core_models.CompanyDetails because it is missing properties that would appear in the second one.
any ideea why this might happen and what I am doing wrong, from what i've seen it uses the models that I import first, no matter what model I tell it to use.
I am using python2.7 and django 1.3.3
All you need it's on the Django documentation
https://docs.djangoproject.com/en/1.3/topics/db/multi-db/
I think that the best solution for your case is a database router.

Django Reusing models

I have Django application with 30+ models. I want to write an application that can take a snapshot of the data in some of the models. I want to write the models once and reuse them in each application so that if I maintain it in one place, the only difference being that when I call python manage.py syncdb the same table are created with different table prefixes.
Is there any way to do this?
This is exactly where the reusable app principle comes into play.
(as explained at the django website)

About 20 models in 1 django app

I have started work on a local app for myself that runs through the browser. Having recently gone through the django tutorial I'm thinking that it might be better to use django rather than just plain python.
There's one problem: I have at least 20 models and each will have many functions. Quite simply it's going to create one huge models file and probably huge views too. How do I split them up?
The models are all related so I can't simply make them into separate apps can I?
This is a pretty common need... I can't imagine wading through a models.py file that's 10,000 lines long :-)
You can split up the models.py file (and views.py too) into a pacakge. In this case, your project tree will look like:
/my_proj
/myapp
/models
__init__.py
person.py
The __init__.py file makes the folder into a package. The only gotcha is to be sure to define an inner Meta class for your models that indicate the app_label for the model, otherwise Django will have trouble building your schema:
class Person(models.Model):
name = models.CharField(max_length=128)
class Meta:
app_label = 'myapp'
Once that's done, import the model in your __init__.py file so that Django and sync db will find it:
from person import Person
This way you can still do from myapp.models import Person
"I have at least 20 models" -- this is probably more than one Django "app" and is more like a Django "project" with several small "apps"
I like to partition things around topics or subject areas that have a few (1 to 5) models. This becomes a Django "app" -- and is the useful unit of reusability.
The overall "project" is a collection of apps that presents the integrated thing built up of separate pieces.
This also helps for project management since each "app" can become a sprint with a release at th end.
The models are all related so I cant's
simply make them into separate apps
can I?
You can separate them into separate apps. To use a model in one app from another app you just import it in the same way you would import django.contrib apps.
Having 20 models in one app might be a sign that you should break it up in smaller ones.
The purpose of a Django app is to have a small single-purpose piece of code, that fits nicelly together.
So, if you had a e-commerce site, you might have a shopping_cart app, a billing app, and so on.
Keep in mind that there is really no problem in apps depending on each other (although it's always better if they can be decoupled), but you should not have an app doing two very distinct things.
The article Django tips: laying out an application might help you. As always, take everything you read with a grain of salt (including this answer).
You can break up the models over multiple files. This goes for views as well.
You can split them into separate files and simply have imports at the top of your main models.py field.
Whether you'd really want to is another question.

Categories