This is really just a "best practices" question...
I find that When developing an app, I often end up with a lot of views.
Is it common practice to break these views up into several view files? In other words... instead of just having views.py, is it common to have views_1.py, views_2.py, views_3.py (but named more appropriately, perhaps by category)?
Splitting views.py
Most of your code probably expects your views to be accessible as myapp.views.viewname. One way I've seen people break up their views but keep this python name is to create a views/ directory. views/__init__.py will have:
from .foo_views import *
from .bar_views import *
from .baz_views import *
Then, in views/foo_views.py, put:
def foo_detail(request, ...):
# your code here
def foo_list(request, ...):
# your code here
def your_other_view(...):
# ...
etc. So you move everything from views.py into files in this directory, make __init__.py, delete views.py, and you're done.
Then, when you import myapp.views, myapp.views.foo_detail will refer to the function that you defined in views/foo_views.py.
Splitting other modules
This strategy should also work fine for admin.py, etc. But if you want to split up models.py like this, you will need to add app_label = 'your_app_name' to the class Meta: of all of your models. For example, unicorn_app/models/unicorns.py could have an entry like this:
class Unicorn(models.Model):
description = models.CharField(max_length=80)
class Meta:
app_label = 'unicorn_app'
(Otherwise, Django imagines that the Unicorn model is part of a Django app named "models", which messes up the admin site. Current through 1.6 - the upcoming 1.7 release will remove this requirement.)
As a general guideline, think about readability and maintainability: the default "views.py" is just a suggestion made by initial scaffolding - you do not have to stick to it.
Usually, files with thousands of lines of code are difficult to maintain, for this I usually try to decompose bigger modules into smaller ones.
On the other hand, the division should make sense - splitting related functions into several files, with lots of imports may make maintenance even more difficult.
Finally, you can also think about completely other ways to simplify your application.
Do you see duplicated code? Maybe some functionality could be moved in a completely different application? And so on.
Another option would be to move some of the functionality into one or more apps. This would allow you to move also forms and templates and keeping things structurized. You don't necessarily need to move the models which saves you from model and data migration.
For example you could have the following structure:
main_app/
|_models.py
|_views.py
|_forms.py
|_urls.py
|_templates/
sub_app_1/
|_views.py
|_forms.py
|_urls.py
|_templates/
sub_app_2/
|_views.py
|_forms.py
|_urls.py
|_templates/
Related
Should a component be its own application?. So we have separate our apps for that reason.
Now reusability does matter in Django. It is trivial to make our apps reusable when each module in the apps does not depends on another apps.
However, It is common to refer a model in another apps by adding ForeignKey('appname.MyModel'). It creates a hard dependency of the Django apps with another apps.
The same thing happened with import of another apps (i.e. from appname import MyModel). It creates a dependencies of the apps to another apps.
If the app contains such dependency of another apps, then it does not seems to be viable to share our apps (i.e. Not reusable).
What do I have to do to make the dependencies loose. And allow me to share my apps without having to hardcode another apps in the app.
So, it's worth noting that we don't really need to depend on your specific apps. We depend instead on having something that satisfies the same interfaces your apps expose.
This is the 'Pythonic' way to do things (sometimes referred to as duck typing as 'if it walks like a duck and quacks like a duck... it must be a duck').
You've had in comments how to solve the ForeignKey problem
To summarise, you can just add the value in settings.py:
MY_FK_MODEL = 'someapp.SomeModel'
and then use it in your models.py like so:
from django.conf import settings
class ReusableAppModel(models.Model):
some_model = models.ForeignKey(settings.MY_FK_MODEL)
So far, so easy; now to solve the import.
We actually already have an example of this from Django itself. Which is the get_user_model() method.
We could make something like that by adding the following in settings.py:
MY_APP_DEPENDENCY = 'myapp.my_module.MyClass'
along with a helper function similar to get_user_model() somewhere in your reusable app. Let's say reusable_app/helpers.py for the sake of argument:
from django.conf import settings
from pydoc import locate
def get_my_app_dependency():
dependency = locate(settings.MY_APP_DEPENDENCY)
# locate() returns None if the class is not found,
# so you could return a default class instead if you wished.
return dependency
Then you can get that class wherever you need it by calling the method:
from reusable_app.helpers import get_my_app_dependency
MyAppDependency = get_my_app_dependency()
app_dep_instance = MyAppDependency()
The summary here is that you can allow users to specify a class/method/whatever as a string in settings.py and then use that to refer to your dependency.
This lets users 'inject' a dependency into your app.
One final note:
Whenever you have an app/module that has lots of dependencies on others, it's worth double checking to see if they really should be separate. You want to avoid creating one giant module satisfying lots of disparate responsibilities, but likewise you want to avoid artificially breaking code up when it doesn't make sense. It's a careful balance.
I m working with django for a small project. I am not sure if the below approach is a best approach.
I have three applications under a project
1) app1, app2, app3
Question:
2) All three applications work with the same model, and is it fine if i keep model itself into different application so that app1, app2, app3 can access it?
ie: 1) modelStore, app1, app2, app3.
Kindly consider it is fresher question!!.
The bottom line is you put your model inside the app, which is the most relevant. Then just import it like
from app1.models import MyModel
this line will work anywhere in your code.
If you're not planning on creating a (standalone) reusable app, it's fine to share functionality across those apps.
However you should always consider if splitting up functionality into different apps is really the best solution if the usage is bound close together.
A different approach could be to have just one app, splitting out forms, admins or models (if that improves readability).
/project_root
/project
__init__.py
settings.py
/app
__init__.py # imports Foo and Bar from foo_models and bar_models
/models
foo_models.py # requires a `class Meta: app_label = 'app'`
bar_models.py # requires a `class Meta: app_label = 'app'`
/forms
foo_forms.py
manage.py
And really, just be consistent whatever you pick, there's nothing worse than inconsistent coding.
I am new to Django and have a little problem with making all the project structure clear and organized and so on.. The MVC stuff in Django is quite easy to use when making a small project. However, when I am trying to get a new layer (application logic, like three-tier architecture) between views.py and models.py I have problem to do so.
I have the following structure:
mysite/
manage.py
app1/
models.py
views.py
logic/
__init__.py
Class1.py
parser.py
...
and I want to load into views.py stuff from Class1.py and parser.py.
How do I do it?
Neither of the following works:
from app1.logic import *
from app1.logic.Class1 import Class1
Also, it would help me if somebody could list me some example of a really huge django project. It looks like either lots of classes and .py files should be in every app folder or everything is in the models.py.. Both look a little disorganised and I'm sure there is a way to make it a little bit clearer (like in Zend or Symfony).
And, I'm working with Python3 and Django 1.5b2.
Thanks.
If Class1 or parser import from views, then you have a circular dependency. You'll need to move any shared code out into a third file.
You might consider though whether you need all those separate files under logic. In Python there's no requirement to have a class in its own file, so maybe you could have a single logic.py instead of a logic directory containing several files.
I was reading over the following code, and the models were structured such that each class/model had a separate file and then it was imported in __init__.py. For example:
# __init__.py
from service import Service
from note import Note
etc...
# service.py (one example of the imports)
from django.db import models
class Service(models.Model):
#: service provider name (e.g. Hulu)
name = models.CharField(max_length=64, verbose_name="Title Name", unique=True)
def __unicode__(self):
return u'Service id=%s, name=%s' % (self.pk, self.name)
Which way is better practice, to have all models in one models.py file, or to have one file-per model? I usually keep all my models for an app in one file, and I had never seen the models separated, which is why I'm asking this question.
If you're talking true "best practice", that would be following the way Django recommends and using just models.py. However, there's a lot of opinion and argument that goes into the this topic. Nevertheless, my recommendations:
If you have a simple app, with only a few models. Stick with the "Django-way" of just a models.py.
If you have a huge app with lots of models and thousands of lines of code, divvying it out is probably better. However, at this point, you should also ask yourself why your app is so huge and if anything can be factored out into auxiliary apps.
Long and short, my personal opinion is that breaking out of the models into separate files is never a good idea. It can in some cases cause problems and I honestly can't see a use case where it's truly justified. Usually, if your app is big enough to warrant doing this, it's actually a sign that you're lumping too much functionality together that would be better delegated out into other apps.
Best practice is to put them in one file. Look at the django source for example.
The reason you've never seen it is because it's practically never done.
If you can justify it somehow then by all means do it, but it's definitely not the recommended structure. People start to explore splitting models when the file gets too large / can be logically separated.
I have a bunch of functions that I created in some views that must be reused in many other views. Do I need to create a class and put those functions in a class? If yes how exactly has to be done in Django and then how do I call and initiate them in the new views?
Django views are just Python functions. You can call other Python functions from them just as you can from any other Python code. Put your functions into a .py file, import it, and invoke the functions.
Of course, it may make sense for other reasons to create a class to hold the functions, but you certainly don't need to in order to call them from views.
The solution would be to create the myfunctions.py file in your app folder and import it in your views. Your views file would look like:
import myfunctions
def my_view(request):
.....
foo = myfunctions.bar()
....
You look to complicated to Django. Django is just another Python application and lives in the Python world. For example you can create file library.py and import this file where is needed (in modules where the function from library is needed). If you need you library's functions to get data from database, just import models in the library.py and use them.
Django doesn't have such a big think as "module". You creating the architecture, you can define what in your case is module. In general this is just simple directory with init.py file inside to be able to import files from there.
Hope that helped.
From my point of view, if you have a lot of functions that are widely used in your project it make sense put all this in some separate application. I create some module named 'contrib' for this purposes. It can avoid some time for maintaining this code in future