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.
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.
can i include the same app url conf within two different root?
I mean, i have this
(r'^event/', include('quip.apps.event.urls')),
but i would like to have that
(r'^event/', include('quip.apps.event.urls')), #display event e.g. event/my-event-slug
(r'^events/', include('quip.apps.event.urls')), #filter events e.g. events/today/somewhere
I need different behavior in my 'quip.apps.event.urls'. the only solution that come in my mind is to create two urls file, but i don't think is a quite really good solution.
(r'^event/', include('quip.apps.event.someurls')),
(r'^events/', include('quip.apps.event.otherurls')),
any ideas? i'm sure this is a silly question.
Yes you can. To keep it modular, I would make urls a package:
(r'^event/', include('quip.apps.event.urls.someurls')),
(r'^events/', include('quip.apps.event.urls.otherurls')),
Where the directory structure would be
event/
__init__.py
urls/
__init__.py
someurls.py
otherurls.py
Also, in urls/__init__.py you could do
from .someurls import *
from .otherurls import *
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.
OK -- I've been working with Django for a few months now and have come across a weird issue. To set it up, here's my webapp structure.
The main Django project is called cpm.
I have a bunch of django apps in the cpm folder. Within each app, I have my models.py file.
Now, when I want to create/use models from other apps I would do something like:
from cpm.products.models import *
assuming an app named products was present. Recently, I started to get some errors saying things like, cannot import XYZ from products. So, after much searching, I changed the line:
from cpm.products.models import *
to
from products.models import *
I just dropped the cpm. part and now it works.
Can someone tell me why this is happening? It seems to be happening on only portions of my apps (I have a bunch within the CPM project). I want to make sure my syntax is accurate as I move forward.
Thanks!
The project root's directory got removed from the python path somewhere along the way, or you removed the __init__.py file from it's root.
On a side note, importing * will lead to issues, especially when you start adding lots of apps. Consider doing from products import models as prod_models. Then doing prod_models.MyModel where you need to reference your models.
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/