I want to know if I've understand the main point of django app usage.
Every app has a models.py file which create tables in our database, correst?
For example I want to create a personal CMS. I should create an app, to create tables for my posts details, and should create an other app to creating tables for my users that want to sign up into my blog, in order to keep their username and password in the database, and I also can create an other app to create a separate tables to save other data..... Do I think correctly?! What are django apps exactly for?
Apps are logical modules. One app can contain several models. Your project could have users and blog apps. users would have User and Group models, blog would have Post, Tag and PostTag models.
Views within single app usually have same URL prefix and their own URL routing.
Within app all database migrations are executed consecutively whereas it's your responsibility to specify dependencies between migrations from different modules.
Try to keep logical bounds between apps as weak as possible.
Related
I made an app(first app) with Django following a tutorial.
And I finally completed a web server with AWS EC2, nginx, uwsgi, mySQL, and Django.
Then I tried to make a new app(second app).
But I found that I put account information(user model) in first app's model.py. Furthermore, I added something like notification functions in first app's model and view etc...
I want to make new app with first app's account and notification, but I am not sure it's possible to split one app to two apps.
I'd like to make a site(project) have three apps which are account apps(including user model, notification, etc.), first app, and second app. Then, I thought second app can use user info like first app. (Is there any better way?)
I just have a questions, how can I split account app from first app without any data loss. Actually I afraid that if I make a problem, it's very hard to restore it. (model, view, url, ...)
My model is following
class Profile(models.Model) # I'd like to split into account app
class Recruit(models.Model) # stay in first app
class Apply(models.Model) # stay in first app
class Comment(models.Model) # stay in first app
I will appreciate if I can get some tips or references.
Thank you.
Create the new app
Move your models to them
Make migrations and fake migrate migrate --fake
Go to database and change the name of tables - Content types - permissions
for help use this one by me GITHUB script to change model names
Inform me if that worked well with you and don't expect it will be straight forward
Don't think about the app as isolated entity. The concept of the app is something that you want to distribute and let other developers reuse. This is not your case.
You refer the site as project and it's normal to have an app to import from another app. I would suggest you call them packages that are part of your projects, yes you add them in your INSTALLED_APPS but at the end are packages.
Try to have a good packages tree where the references are top-down and not crossed referenced.
Remember: you don't build the application for the database, you build it for the Domain, the database is just a Persistence implementation detail.
From this article.
I'm build a Django app with a number of models (5-10). There would be an admin side, where an end-user manages the data, and then a user side, where other end-users can only read the data. I understand the point of a Django app is to encourage modularity, but I'm unsure as to "where the line is drawn" so-to-speak.
In "best practices terms": Should each model (or very related groups of models) have their own app? Should there be an 'admin' app and then a 'frontend' app?
In either case, how do the other apps retrieve and use models/data inside other apps?
Apps are logical separators. For example, if your site has blogs, polls and feeds, you might have blog, poll and feed apps. Each app might have multiple models (Blog and Post models for blogs for example), but be separated from each other by function.
You don't strictly have to separate things into separate apps if you don't want to. Splitting things into apps does help a lot with overcrowding. If you think you will grow beyond 10 models you might consider splitting up before it becomes too hard (django really doesn't like you to move stuff between apps).
As for accessing things from other apps, each app is a module, so all you do is
from app1.models import App1Model
and you are all set.
Python\Django is modular.
App should include just those models which usually solve 1 concrete task.
If some of models from p.1 can be usefull in other tasks, then probably would be better to create a new apps for those models. Ie if some models are shared between multiple tasks then there is a logic to make a new apps with those models.
For example you have a forum app. This forum has such features like, polls, registrations, PM, etc. Logically everything seems to be combined together. However, if your site is just a forum - ok, but if there are other content, for example blogs with comments, then "registration model" can be made as a separate app and can be shared between parts of site such as "blogs with comments" and "forum".
Regarding admin\frontend. Ive seen apps\projects with more than 10 models together. Based on the forum example above, if the admin part does not do any task out of scope of your app, then I would make admin and front-end inside of one app. Otherwise, if admin has any relation to another task, which is out of scope of your main app - admin should be as a seperate app.
Background: I have 5 independent Django projects which I am attempting to combine in to 1 Django project composed of several apps. In other words: projA has appA, projB has appB & projC has appC, etc. I want 1 masterProj that has appA, appB & appC.
Currently each app connects to it's own independent database (the apps don't share data). Each project uses Django user authentication, Django registration, taggit, profiles, comments and sorl-thumbnail.
I'm using Django 1.4 and setup database routing according to this stackoverflow answer so that, once combined into one project, each app in the newly combined Django project is still able to connect to its own database. That went smoothly, but I started running into trouble with things like user authentication and taggit:
1) As mentioned before, each app connects to a different database and each of those databases has a table named 'auth_user'. However, I've found that all read/write calls to the auth_user table (regardless of which app makes the read/write call) are routed to the default database (in this case appA's database):
# settings.py:
DATABASES['default'] = DATABASES['appA']
DATABASE_ROUTERS = ['appA.db.DBRouter', 'appB.db.DBRouter', 'appC.db.DBRouter']
# appA/dbrouterA.py (appB, appC routers are identical this, replacing 'appA' with 'appB', etc.)
class DBRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'appA':
return 'appA'
if model._meta.app_label == 'auth':
return 'appA'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'appA':
return 'appA'
if model._meta.app_label == 'auth':
return 'appA'
return None
2) Assuming I get the routing working, if a user logs into appA, I don't want them to be logged into appB. I have seen many people post the reverse question (they want their apps to share user credentials) but has anyone successfully used Django user authentication in several independent apps in the same project? If so, how did you do this?
3) I get the following error from my taggit code, but I haven't been able to figure out how to pass the "related_name" parameter to taggit. I'm using the basic implementation of taggit - not subclassing anything:
# appA/models.py
tags = TaggableManager(blank=True)
# appB/models.py
tags = TaggableManager(blank=True)
Error:
appA.userprofile: Accessor for m2m field 'tagged_items' clashes with related m2m field 'TaggedItem.userprofile_set'. Add a related_name argument to the definition for 'tagged_items'.
appB.userprofile: Accessor for m2m field 'tagged_items' clashes with related m2m field 'TaggedItem.userprofile_set'. Add a related_name argument to the definition for 'tagged_items'.
4) I'm starting to get the feeling that combining all these apps is a slippery slope; that later down the line I might run into problems with sorl-thumbnail or comments that haven't surfaced yet. Has anyone successfully combined apps into a single project? Or am I trying to do something that Django doesn't fundamentally support?
Thanks in advance for the help!
Django's architecture is designed to revolve around a Django project and several Django applications. The project itself is nothing more than your settings and main URL configuration module, while the applications are simple packages that follow a few file conventions.
Now, the applications themselves are never coupled to a particular project (they can be coupled to other applications by referencing them, though). The idea is to allow you to retain the freedom to design how your project's sources are structured and one approach that's common for most Django projects out there is to distribute Django applications under the project's top-level package, like most Python applications. This approach makes it convenient to get a holistic view of all the features a project provides (when you apply meaningful application labeling), to create namespaces and provides the developers a convenient and organized path of access to particular project sources.
This works great both for large projects and when you want to collocate and merge several different projects that reuse similar designs and approaches across. While this is going to affect only how your project is structured, choosing whether or not you'll have a configuration for a single Django project or several Django projects for your fixed set of Django applications has some important ramifications.
When you create a Django project, your basically plugging in Django applications in to the framework's instrumentation and exposing application behavior, as we understand it in Web applications, by configuring and including mapping patterns for URLs and views from your Django applications.
The point is that you can reorganize the sources in any way that works for you. Your packages can be organized like proj.appA, proj.appB, etc. or proj.common1, proj.common2, proj.projA.app1, proj.projA.app2, proj.projB.app1, it's really up to you.
What you should know is that you don't need a single settings and URL module and resort to database routing and managing database connections, you may just as well have a settings and URL module for each project, that reference different applications and expose different behavior. With per project database settings, your already reusing code and keeping the database data and state distinct for each project at the same time.
I am begginer in the Django world, I developed some "information sites" (nothing complicated) but this week my boss order me to make a migration of a big software that has 7 modules.
So I went to read the documentation page and search in google for how I could design this software using Django. I know that the every "module" can named as "app", so I create a new project and one app for every module (I dont know if it was right because the modules will not be public).
The problem is that now I don't know what is the next step.
All my apps can share data (every app has its owns models but sometimes one app has a model that was related to the models in other apps)?
Where do I write the code for the login process (I create a manageUsers app that was thinked to handle the registration, edit, share and validate profile of the current or new user ) and we can be able to share this session data accross the apps?
I need one more app for put the website information (like contact, about, pricing ...)? I use Python 2.7, Django 1.3, Memcached and Mysql 5.
If someone can help me or tell me where it may clarify these questions because most explains how to develop using only one app and in the IRC got no reply or else I must be write all the code in one app?
Best Regards
A good place to start (dated, but worth reading; look at user comment bubbles too): http://www.djangobook.com/en/2.0/ . Chapter 1 - 10 are essential reading. You can pick-and-choose to read the remaining chapters, if desired.
Yes, all Django Apps can share data with one another. You make multiple Django Application's, housed under a single Django Project. The Project sets up a common database to use, and each Application creates Models which use said database. App1 can talk to App2 and vice-versa.
Django Project (one) <----->> (many) Django Application
Typically you separate Apps based on common function. User accounts get their own app (see Auth below). Blog postings get another. A Google Maps interface will get another. User subscriptions, another.
For user accounts and login, Django provides the Auth Module. You can have user accounts stored directly in Django, or configure it to talk to something else, like Active Directory. Auth works "pretty good" out of the box, though I personally customized mine a bit to allow 255-character email addresses as usernames (by default, it limits to 40 characters). Chapter 14 in the Django book might be a little easier to read than the official Auth docs. If you do use Auth, you don't have to make your own Django Application, since Auth already is one! You just install it in settings.py and you're golden.
Your Django structure will likely look something like this:
/Project/
__init__.py
manage.py
settings.py
urls.py
App1/
__init__.py
forms.py
models.py
views.py
templates/App1/
template1.html
template2.html
App2/
...
App2 can access the data-models of App1 by doing: from Project.App1.models import someModel
For me, rules are simple.
If you need to copy-paste some code from one project to another - make an app for it
If one of app's modules code is bigger than 1k lines and/or hard to maintain - look for something to move in separate app
Group functionality into apps to minimize cross-linking between them
For interconnection you can use signals and sessions
According to the documentation:
An app is a Web application that does
something -- e.g., a weblog system, a
database of public records or a simple
poll app. A project is a collection of
configuration and apps for a
particular Web site. A project can
contain multiple apps. An app can be
in multiple projects.
However, what are other examples of what makes an "app"?
What makes an app (for us) is one thing:
An App Is The Unit Of Reuse
If we might want to split it off to use somewhere else, it's an app.
If it has a reusable data model, it's an app. User Profiles: App. Customers: App. Customer Statistical History (this is hard to explain without providing too many details): App. Reporting: App. Actuarial Analysis: App. Vendor API's for data gathering: App.
If it is unique and will never be reused (i.e., customer specific) it's an app that depends on other apps. Data Loads are customer specific. Each is an app that builds on an existing pair of apps (Batch Uploads, and Statistical History)
Django apps are bundles of reusable functionality. When starting off it's easy to just use one custom app for your project, but the "Django way" is to break it up into separate apps that each only do one thing. You can take a look at django.contrib for examples of really well made reusable apps.
A recent example of mine: a client needed a way to import CSV data into the Django models. The easiest way would be to just add a model with a FileField and write a quick parser for the specific format of what they are uploading. That would work fine until the format changed and I had to go make the parser match. But this is a commonly repeated task (importing data) and unrelated to the existing app (managing that data) so I broke it out on its own. This pluggable app can import data for any active model. Now the next time a client needs import functionality I just add this code to installed_apps and run syncdb.
It's a judgement call when to break out an app onto its own, but the rule of thumb for me is if I'm likely to do something again I'll take the extra time to make it a generic app. That means I've created some tiny apps (some just contain a template tag), but it's little overhead for the future gains.
User management could very well be an app, if you are not going to use Django's built in user framework.
It has user interfaces and defined models for stored data, and it is really separate from the Blog or the Wiki application (although the information will be shared).
As long as both applications are in the same 'project' they should use the same settings for the DB. You should be able to by just making sure the proper models are imported where you are trying to use them.
See this link for a little more information.