How to bind multiple reusable Django apps together? - python

I try my best to write reusable Django apps. Now I'm puzzled how to put them all together to get the final project.
Here is an example of what I mean:
I have a picture app that stores, resizes and displays images. Also I have a weblog app that stores, edits and displays texts. Now I want to combine these two to show blog posts with images.
To do that I could put foreign key fields in the blog to point at pictures. But then the blog could not be used without the picture app. Also I could create a third app, which is responsible to connect both.
What is the 'best practice' way of doing it ?
EDIT: Thank you for your very good answers, but I'm still looking for more practical example of how to solve this problem. To complete my example: Sometimes it would be nice to use the blog app without the picture app. But if I hard code the dependency it is no longer possible. So how about 3rd app to combine both ?

Introduction talk in the bottom of the answer (more straight to the answer). I will assume that you have one app for text handling called Text and one app for picture handling called Pictures and a third app for blogging called Blog.
Big picture
You will need to study the manual about the template language for python programmers. The idea is that each thing is in its own app and that you have a third app that connects everything. The apps should then supply its models and views as you like them (just remember to keep you focus on what the app should do) and also supply a set of templatetags.
How to make inclusion tags
Make inclusion tags and it is really easy! It will remind you of writing normal views.
Create a directory templatetags in you app folder. Also create a __init__.py file in this templatetags (so the directory becomes a python package).
Then create a python file. The name is important, you will use this in {% load xyz %} in the templates that will use your app. For instance if call the file picturestags.py, you will call
{% load picturestags %} in all templates that will use it.
First in the file add some politics you need not to think much about, just include this before anything else:
from django.template import Library
register = Library()
Then add the tags by defining functions with the same name as your tag. I will call it display_picture in the example and it will take one argument url. The function should create a dictionary that you will use in a template. My example will just display the picture the url is pointing to.
#register.inclusion_tag('pictures/display_picture.html')
def display_picture(url):
return {'picture': url}
Create the path templates/pictures in your app and create the file display_picture.html inside containing:
<img src="{{ picture }}" />
As you probably understand, the #register makes this a tag, what is inside the dictionary display_picture returns are what you can use in display_picture.html. Very much like your normal view functions.
In the end you will end up with these files:
pictures/
__init__.py
models.py
views.py
tests.py
templates/
pictures/
display_picture.html
templatetags/
picturetags.py
That is all you need to add to your Picture app. To use this in your Blog app, you need to add Pictures to your INSTALLED_APPS. Then in the templates, where you need to use your own newly home baked tag first load it: {% load picturestags %} then just add the tag {% display_picture https://www.google.com/intl/sv_ALL/images/logos/images_logo_lg.gif %} like this:
{% load picturestags %}
<html>
<body>
{% display_picture https://www.google.com/intl/sv_ALL/images/logos/images_logo_lg.gif %}
</body>
</html>
Results
This is just a small example but you can see that it is very easy to expand this. Your blog could connect the Text and Pictures app by importing their models and foreign key them. There is you connection Text and Pictures for a certain blog post. Your blog_post.html-template could look like (simplified):
{% load picturestags %}
{% load texttags %}
<html>
<body>
<h1>{{ subject }}</h1>
<div class="article">{% article_to_html articleid %}</div>
<div class="article_picture">{% display_picture %}</div>
</body>
</html>
Notice that only the Blog has dependencies and it is dependencies it should have (no blog without text and pictures...but pictures can live without text). The look and placement should be and can be controlled by CSS and DIV/SPAN-tags. In this way you can take your Picture app and give it to someone who has no idea about Text app and use it, displaying pictures in different ways probably without ever touching your code!
Inclusion tags is the only thing I know of since I just learned this yesterday. I think it is a convenience provided by Django to make life simple. On the documentation page there are a whole lot more (including how to make "real" tags the hard way without "shortcuts"). So if you find this method to limited, read the documentation...it has lots of examples. It also discusses how to make filters, simple_tags, thread considerations and other advanced stuff.
Introduction
I had this exactly this problem as you and I also wanted something different than the answers I read (I don't say the answers was bad, they helped me learn a lot and gave me insights, but I wanted this I am writing now). I managed to figure something out that is not very obvious, thanks to your question and definitely thanks to Stack Overflow so this is my contribution back even to a half year old question that is probably abandoned (might help a googler or two)!
I also got a lot of inspiration from Google Tech Talk Reusable Apps. In the end (43 minutes) he mentions some good examples like django-tagging which is what he says a model for how to write reusable apps. That gave me the idea for all this, because that is the way django-tagging solves this very problem we had/have.
Now after I written all this (took an hour), I feel for the first time that I might contribute instead of just google and follow what others are doing or complaining that others are not writing how I need to do things. For the first time I am taking my responsibility of writing my view so others can google this (just had to write this paragraph :-) because it feels really great, even if it might be shredded to pieces or ignored and forgotten).

Think of it in the same way that you would use any 3rd-party app in your project. "Re-usable" doesn't mean "without dependencies". On the contrary, you'd be hard-pressed to find an app that doesn't have at least one dependency, even if it's just dependent on Django or core Python libraries. (While core Python libraries are usually thought of as "safe" dependencies, i.e. everyone will have it, things do sometimes change between versions of Python, so you're still locking your app into a specific point in time).
The goal of re-usuable is the same as that of DRY: you don't want to write the same code over and over again. As a result, it makes sense to break out functionality like a picture app, because you can then use it over and over again in other apps and projects, but your picture app will have dependencies and other packages will depend on it, as long as there are no circular dependencies, you're good (a circular dependency would mean that you haven't actually separated the functionality).

This is a good question, and something I find quite difficult to manage also. But - do you imagine these applications being released publicly, or are you only using them yourself? If you're not releasing, I wouldn't worry too much about it.
The other thing is, dependencies are fine to have. The pictures app in your example sounds like a good candidate to be a 'reusable' app. It's simple, does one thing, and can be used by other apps.
A blog app on the other hand usually needs to consume other apps like a picture app or a tagging app. I find this dependency fine to have. You could try to abstract it a little, by simply linking to a media resource that was put there by your picture app.
It's all just a little bit of common sense. Can you make your apps slim? If yes, then try to create them so they can be reused. But don't be afraid to take dependencies when they make sense. Also, try to allow extension points so you can potentially swap out dependencies for other ones. A direct foreign key isn't going to help here, but perhaps something like signals or Restful APIs can.

I am a Django newbie and I faced the same problem. It is shameful how there's so much buzz about reusable apps in the Django community, but not a single authoritative reference on how to connect them
in a project without hard coded dependencies.
I have been working on a new Django project and I wanted to set up my models to avoid hard coding as much as possible. This is the pattern that I used.
Layout
project_root/
core/
models/
mixinmodels1.py
mixinmodels2.py
...
utils.py
...
app1/
models/
__init__.py
base.py
basemixins.py
mixins.py
concrete.py
/signals
__init__.py
handlers.py
utils.py
...
app2/
...
...
App models
base.py : This module implements only the 'reason for existence' of that app in abstract classes.
Rules are:
This module usually only imports from the core app. It usually does not import anything from other apps in the same project.
An exception to the above rule is when the 'reason for existence' assumes the existence of another app. For example, a group app assumes that there is an user app somewhere. In this case, the way to link them is:
# project_root/settings.py
AUTH_USER_MODEL = 'app_label.UserModel'
# project_root/groups/models/base.py
from django.conf import settings
and then using settings.AUTH_USER_MODEL to refer to the user model
Use this pattern for all apps, not just the user app. For example, you should also do
# project_root/settings.py
GROUP_MODEL = 'app_label.GroupModel'
If using the above pattern, only assume the functionality provided by base.py of the other app
to which you are linking. Do not assume the functionality of elaborate concrete classes (I will discuss where to put concrete classes shortly)
Of course, importing from django, third party apps and python packages is allowed.
Make sure that the assumptions that you make in base.py of any app is rock solid and would not
change much in the future. A good example is django-registration by James Bennett. Its an old app, but its appeal did not wane because it made rock solid assumptions. Since good reusable apps do one thing well, it is not difficult to find that set of assumptions.
basemixins.py: This module should implements plugs to the concrete models of that app. A 'plug' to a model M is any model that contains a foreign key to the model M. For example:
# project_root/groups/models/basemixins.py
from django.conf import settings
from django.db import models
class BaseOwnedByGroup(models.Model):
"""
This is a plug to the group model. Use this
to implement ownership like relations with
the group model
"""
owner = models.ForeignKey(settings.GROUP_MODEL,
related_name = '%(app_label)s_%(class)s_owner',
verbose_name = 'owner')
# functionality and manager definitions go here.
class Meta:
abstract = True
app_label = 'groups'
BaseOwnedByGroup is a 'plug' to the group model. The rules here are the same as 'base.py`
While defining 'plugs' in basemixins.py, only assume functionality provided by base.py.
Import only from core, django, third party apps and python packages.
mixins.py : This module should be used for two purposes
To define elaborate 'plugs', which assumes the functionality of the elaborate concrete classes but not the relationships with other apps. The elaborate plugs should ideally inherit one of the 'base plugs' defined in basemixins.py.
To define mixin models (that are not 'plugs') which can be used by the concrete classes of that app.
concrete.py : This module should be used to define (you guessed it) concrete classes of that apps and to set up relationships with other apps. In short, this module assumes your project and all the
functionality you want to provide in it.
Relationships to other apps should be set up as follows:
To establish a one to one or many to one relationship with model M of app another_app, do the following:
# project_root/another_app/utils.py
def plug_to_M_factory(version_label):
"""
This is a factory method which returns
the plug to model M specified by
version_label
"""
if version_label == 'first_version':
from another_app.models.basemixins import BasePlugToM
return BasePlugToM
if version_label == 'second_version':
from another_app.models.mixins import PlugToM
return PlugToM
...
# project_root/groups/models/concrete.py
from groups.models.base import BaseGroup
from another_app.utils import plug_to_M_factory
PlugToMClass = plug_to_M_factory(version_label = 'second_version')
class ConcreteGroup(BaseGroup, PlugToMClass):
# define your concrete model
class Meta:
app_label = 'groups'
To establish a many to many relationship, the recommended way is to use a through model. Inherit the correct plug in the through model in the exact same way (as we did in the ConcreteGroup model)
signals : While setting up relationships, often we have to perform operations on a model M of app app1, when model N of app app2 changes. You can use signals to handle that. Your handlers can assume the functionality of the concrete sender, but often they don't need to. Assumption of the base version of the sender in base.py is enough. This is why it is a good idea to always use settings.ModelName to refer to a concrete model. You can extract out the model class from the settings.ModelName string by either using ContentType or using a project wide get_model_for_settings function as follows:
# project_root/project/utils.py
from django.db.models import get_model
from django.core.exceptions import ImproperlyConfigured
def get_model_from_settings(model_string):
"""
Takes a string of the form 'app_label.model' as input, returns the
appropriate model class if it can find it.
"""
try:
app_label, model_name = model_string.split('.')
except ValueError:
raise ImproperlyConfigured("function argument must be of the "
"form 'app_label.model_name', got '%s'" % model_string)
model = get_model(app_label, model_name)
if model is None:
raise ImproperlyConfigured("function argument refers to model "
"'%s' that has not been installed" % model_string)
return model
core : The core app is a special app which stores project wide mixin functions.
These mixins should not assume anything about any other app. Only exception to this rule is mixins that rely on base functionality of settings.AUTH_USER_MODEL. This is because you can safely assume that most projects will have an user model.
Of course imports from django, third party and python packages are still allowed
Remember that all base.py and basemixins.py modules are allowed to import from core.
Finally for everything to work as intended, import your models in models/__init__.py of every app.
The advantages that I find from following this scheme is:
The models are reusable. Anyone can use the abstract base models and mixins to design their own concrete model. base.py, basemixins.py and related factory methods can be bundled together with a bare bones concrete model and shipped in a reusable app.
The apps are extendable. All mixins are versioned and there is a clear inheritance scheme.
The apps are loosely coupled. External mixins are accessed via factory methods and external models are referred to using django.conf.settings.
The apps are self contained. Any changes in an app will most likely break that app and that app only. Other apps will most likely remain unscathed. Even if external apps break, the place where this
could happen is clearly marked.
I have been using this scheme to reduce coupling between my apps. I am not an experienced Django programmer, and I have a lot to learn, so any feedback is appreciated.

Related

Where should custom object managers that are to be shared between apps go?

My Django app has several apps, each with their own models.py. I also have an api app which provides a REST API.
For model A, I often wanted to get data paginated a certain way (the data-tables way). I wanted to do this in a few places (inside the api app and some main UI apps), so I created a custom object manager PaginationManager and attached it to model A. Then
Life was good and DRY, but now another model B needs to be gotten in a paginated way. I would like to use the same PaginationManager, but which app should it go in? Does it belong outside of any app? It seems like a lot of business logic to be putting in a util folder or something.
Best practice would be to make it as general as possible and extract it into a lib or utils app that can be reused by all of your apps.
I typically will have a utils app that contains thinks like paginators.py, serializers.py, mixins.py and so on. Usually the more generic and reusable the better.

What is a good Django workflow?

I'm a beginner to Python and Django.
When starting a new project what do you do first before diving into the code?
For example, one could take the following steps:
Configure the settings.py file first
Configure models.py to lay out data structure
Create template files
Define the views/pages
Syncdb
etc
So my question is, what is a good workflow to get through the required steps for a Django application? This also serves as a checklist of things to do. In the definitive guide to Django, the author talks about approaching top down or bottom up. Can anyone expand further on this and perhaps share their process?
Thanks.
Follow the Agile approach. Finish one small case, from the start to the end. From the models to the tests to user experience. Then build on it. Iterate.
Thats the right way to software development.
To do it efficiently, you need: (don't bother right away, you will need it.)
Automated schema migration, automated build system, auto updating and deployment. - None of these, django has got anything to do with. Use pip, fabric, hudson, twill and south appropriately.
Take care not to over burden yourself with all these right away, particularly since you say, you are beginning.
the required steps for a Django application?
There are two required steps.
Write the settings. Write the urls.py
The rest of the steps are optional.
This also serves as a checklist of things to do.
Bad policy. You don't need a checklist of Django features. You need a collection of use cases or user stories which you must implement.
For some reason, you've omitted the two most important and valuable features of Django. Configure the default admin interface and write unit tests. The default admin interface is very high value. Unit testing is absolutely central.
You do it like this.
Gather use cases.
Prioritize the use cases.
Define the actors. The classes of actors becomes groups in the security model.
Define enough "applications" to satisfy the first release of use cases. Define the url structure. Cool URL's don't change.
Build the first use case: models (including security), admin, urls, tests, forms, views and templates. Note that these are the file names (models.py, admin.py, ...) except for templates. Also note that forms and admin should be defined in separate modules even though this isn't required. Also note that templates will be split between a generic templates directory for top-level stuff and application-specific templates.
Build the second use case: models (including security), admin, urls, tests, forms, views and templates.
...
n. Package for release. Tweak up the settings. Configure database and mod-wsgi
I personally can't make a template without writing the views (unless it's a photoshop draft) but in general that's the way I go after I have a plan.
What's extremely important for me is that I don't dive head-first into the code, and that I spend time mocking up the model structure based on the "screens" or "pages" that the user will see.
Once I have a user experience defined, I make sure the backend is robust enough to handle that experience. If I don't visualize the user experience, details get left out that are certainly accomplishable in the shell but not ideal for the website, default django admin, etc.
There are always tradeoffs between agile development and a huge spec: I think there's an important balance. Agile is good: there's no point planning every detail before writing your first line of code, as your needs will change by the time you get to the end. You don't know how your users will really use the site.
On the other hand, without a plan, you can end up with a messy foundation that affects all future code.
An educated guess is a good start. Don't think or assume too much, but definitely have a clear idea how your users will interact with your site for stage 1.
Always try to remember about a DRY rule. For example, why to write RequestContext every new view is defined, where you can simply write a function once, which will add it for you. Good description is here in another topic.
Try to keep a code written one way. Each time you upgrade a schema of your view, edit it in all already written views. That will help keep your code clear and save a lot time for you in future.
Generally good rule, and how do I write my applications is the rule of small steps. Start with writing a settings and urls, then add one model and one view. When it works, modify - add another models or another views. You won't even notice, when your project becomes bigger and bigger.
And the last useful rule for clarity of all the source. Keep files in folders. If you have two subsites based one one (for example "accounts" and "blogs") create two directories names the same. Remeber to put init.py file in each directory. It's really easy to forget. With this practice it's easy to write models and views dedicated to each category. By the way it's a good practice to keep urls like in a tree structure. Main urls.py should contain only links like this one:
(r'^accounts/', include('your_main_name.accounts.urls')),
and of course all media, static, css and so on. In accounts directory urls keep:
urlpatterns = patterns('your_main_name.accounts.views',
url(r'^$', 'index', name='index'),
)
with all views subdirectories.
Last one - keep code clear with actuall django version. Remeber, that the 3.0 release is comming soon.
Hope this will help.
I find that my process varies depending on a lot of variables, mainly whether I know something will work or if I'm experimenting and also whether I'm developing on my production server or in a development environment.
For example, I often do my development directly on the deployment server (most of my work is for intranet projects so there isn't any security risk, etc). But when I do this I really need to make sure the settings and urls are setup first and that gunicorn and nginx are configured.
If I know something should work, or am setting up a generic base set of code, sometimes I'll do all that coding for views and models before I even get enough setup to even run the development server. But when experimenting with new code I find it's good to be able to test every step of the way, so in that case you need your servers running.
In general I do settings, models, syncdb, views, urls, templates, collectstatic, graphics/aesthetics
In general I leave my base.html very plain until the everything else is working, then I add css/js etc.
I guess my point here is that there isn't really a wrong answer for how you do it, and there isn't even only one best practice (as far as I'm concerned). When you do more work, you'll find what you are comfortable with and it'll even vary from project to project.
Good luck, hopefully you learn to love django!
here is something I do in general,
configure basic settings
configure root url.py
configure settings, url.py for static (media) files
create model
sync db
write views (use simple template, if needed)
once you are done with back end implementation
think about UI
prepare styles, scripts
start working on template implementation

Django: "projects" vs "apps"

I have a fairly complex "product" I'm getting ready to build using Django. I'm going to avoid using the terms "project" and "application" in this context, because I'm not clear on their specific meaning in Django.
Projects can have many apps. Apps can be shared among many projects. Fine.
I'm not reinventing the blog or forum - I don't see any portion of my product being reusable in any context. Intuitively, I would call this one "application." Do I then do all my work in a single "app" folder?
If so... in terms of Django's project.app namespace, my inclination is to use myproduct.myproduct, but of course this isn't allowed (but the application I'm building is my project, and my project is an application!). I'm therefore lead to believe that perhaps I'm supposed to approach Django by building one app per "significant" model, but I don't know where to draw the boundaries in my schema to separate it into apps - I have a lot of models with relatively complex relationships.
I'm hoping there's a common solution to this...
Once you graduate from using startproject and startapp, there's nothing to stop you from combining a "project" and "app" in the same Python package. A project is really nothing more than a settings module, and an app is really nothing more than a models module—everything else is optional.
For small sites, it's entirely reasonable to have something like:
site/
models.py
settings.py
tests.py
urls.py
views.py
Try to answer question: "What does my
application do?". If you cannot answer
in a single sentence, then maybe you can
split it into several apps with cleaner
logic.
I read this thought somewhere soon after I've started to work with django and I find that I ask this question of myself quite often and it helps me.
Your apps don't have to be reusable, they can depend on each other, but they should do one thing.
What is to stop you using myproduct.myproduct? What you need to achieve that roughly consists of doing this:
django-admin.py startproject myproduct
cd myproduct
mkdir myproduct
touch myproduct/__init__.py
touch myproduct/models.py
touch myproduct/views.py
and so on. Would it help if I said views.py doesn't have to be called views.py? Provided you can name, on the python path, a function (usually package.package.views.function_name) it will get handled. Simple as that. All this "project"/"app" stuff is just python packages.
Now, how are you supposed to do it? Or rather, how might I do it? Well, if you create a significant piece of reusable functionality, like say a markup editor, that's when you create a "top level app" which might contain widgets.py, fields.py, context_processors.py etc - all things you might want to import.
Similarly, if you can create something like a blog in a format that is pretty generic across installs, you can wrap it up in an app, with its own template, static content folder etc, and configure an instance of a django project to use that app's content.
There are no hard and fast rules saying you must do this, but it is one of the goals of the framework. The fact that everything, templates included, allows you to include from some common base means your blog should fit snugly into any other setup, simply by looking after its own part.
However, to address your actual concern, yes, nothing says you can't work with the top level project folder. That's what apps do and you can do it if you really want to. I tend not to, however, for several reasons:
Django's default setup doesn't do it.
Often, I want to create a main app, so I create one, usually called website. However, at a later date I might want to develop original functionality just for this site. With a view to making it removable (whether or not I ever do) I tend to then create a separate directory. This also means I can drop said functionality just by unlinking that package from the config and removing the folder, rather than a complex delete the right urls from a global urls.py folder.
Very often, even when I want to make something independent, it needs somewhere to live whilst I look after it / make it independent. Basically the above case, but for stuff I do intend to make generic.
My top level folder often contains a few other things, including but not limited to wsgi scripts, sql scripts etc.
django's management extensions rely on subdirectories. So it makes sense to name packages appropriately.
In short, the reason there is a convention is the same as any other convention - it helps when it comes to others working with your project. If I see fields.py I immediately expect code in it to subclass django's field, whereas if I see inputtypes.py I might not be so clear on what that means without looking at it.
I've found the following blog posts very useful about django applications and projects:
http://www.b-list.org/weblog/2006/sep/10/django-tips-laying-out-application/
http://web.archive.org/web/20080302205555/www.pointy-stick.com/blog/2007/11/09/django-tip-developing-without-projects/
In principle, you have a lot of freedom with django for organizing the source code of your product.
If so... in terms of Django's project.app namespace, my inclination is to usemyproduct.myproduct, but of course this isn't allowed
There is nothing like not allowed. Its your project, no one is restricting you. It is advisable to keep a reasonable name.
I don't see any portion of my product being reusable in any context. Intuitively, I would call this one "application." Do I then do all my work in a single "app" folder?
In a general django project there are many apps (contrib apps) which are used really in every project.
Let us say that your project does only one task and has only a single app (I name it main as thethe project revolves around it and is hardly pluggable). This project too still uses some other apps generally.
Now if you say that your project is using just the one app (INSTALLED_APPS='myproduct') so what is use of project defining the project as project.app, I think you should consider some points:
There are many other things that the code other than the app in a project handles (base static files, base templates, settings....i.e. provides the base).
In the general project.app approach django automatically defines sql schema from models.
Your project would be much easier to be built with the conventional approach.
You may define some different names for urls, views and other files as you wish, but I don't see the need.
You might need to add some applications in future which would be real easy with the conventional django projects which otherwise it may become equally or more difficult and tedious to do.
As far as most of the work being done in the app is concerned, I think that is the case with most of django projects.
Here Django creators points out that difference themselves.
I think that thinking about Apps as they have to be reusable in other projects is good. Also a good way of thinking about Apps in Django provide modern web applications.
Imagine that you are creating big dynamic web app basing on JavaScript.
You can create then in django App named e.g "FrontEnd" <-- in thins app you will display content.
Then you create some backend Apps. E.g App named "Comments" that will store user comments. And "Comments" App will not display anything itself. It will be just API for AJAX requests of your dynamic JS website.
In this way you can always reuse your "Comments" app. You can make it open source without opening source of whole project. And you keep clean logic of your project.

Shifting thinking from CakePHP to Django - a monolithic views file?

I'm trying to get started with Django, and have previously worked with CakePHP, and so my MVC background comes out of that. I'm aware of Django's slightly different MTV architecture, and am fine with the monolithic model files - multiple classes in one file I can handle just fine.
But I'm confused about how to do the views (which are roughly analagous to controllers in MVC, correct?). The examples I've seen just have one views.py that has methods like index(), view(), etc. But if I have a bunch of users that create and own widgets that they can share, for example, I want to have /users/view that runs view() for the users model, and /widgets/view that runs view() for the widgets model.
I don't see any way to separate those out, and don't know what the correct/conventional/right way is to do so. I may just be having trouble wrapping my head around Django's way of doing things, too. Should I have methods in view.py that are user_view and widget_view? That seems very clunky.
Or should I have user_view.py or even user/view.py that contains index() and view()? Could I reference those from the URL routing? How are things generally done with Django and this kind of thing?
This may ultimately be related to (or even solved by) this answer, but I'm asking more as a question of what convention and the right way to think about such things is.
Additionally, shouldn't the docs/examples be clearer on this? I've been impressed by the docs thus far, but I'm pretty sure most web apps will deal with more than one "object," and it seems to me that this would come up pretty often.
Python view files are just Python modules. The views themselves are just functions that can live anywhere you like - the module doesn't even have to be called views.py. The urlconf (in urls.py) can refer to views anywhere at all.
One obvious way of separating things out is into separate applications, which is covered well in the documentation - you can also have separate urls.py files for each app and use include in the main site-level urls.py to include all the sub-files.
But there's nothing to stop you sub-dividing the views in a single app into multiple files - eg by creating a views module, containing a (blank) __init__.py and as many other view files as you like.
Or, if you really do have views associated only with a particular model - and you'd be surprised how seldom that is the case - again, you could make your views classmethods on the model class itself. All a view has to do is to accept a request, and any other parameters, and return a response.

MVC and django fundamentals

Pretty new to this scene and trying to find some documentation to adopt best practices. We're building a fairly large content site which will consist of various media catalogs and I'm trying to find some comparable data / architectural models so that we can get a better idea of the approach we should use using a framework we've never made use of before. Any insight / help would be greatly appreciated!
"data / architectural models so that we can get a better idea of the approach we should use using a framework we've never made use of before"
Django imposes best practices on you. You don't have a lot of choices and can't make a lot of mistakes.
MVC (while a noble aspiration) is implemented as follows:
Data is defined in "models.py" files using the Django ORM models.
urls.py file maps URL to view function. Pick your URL's wisely.
View function does all processing, making use of models and methods in models
Presentation (via HTML templates) invoked by View function. Essentially no processing can be done in presentation, just lightweight iteration and decision-making
The model is defined for you. Just stick to what Django does naturally and you'll be happy.
Architecturally, you usually have a stack like this.
Apache does two things.
serves static content directly and immediately
hands dynamic URL to Django (via mod_python, mod_wsgi or mod_fastcgi). Django apps map URL to view functions (which access to database (via ORM/model) and display via templates.
Database used by Django view functions.
The architecture is well-defined for you. Just stick to what Django does naturally and you'll be happy.
Feel free to read the Django documentation. It's excellent; perhaps the best there is.
first, forget all MVC mantra. it's important to have a good layered structure, but MVC (as defined originally) isn't one, it was a modular structure, where each GUI module is split in these tree submodules. nothing to use on the web here.
in web development, it really pays to have a layered structure, where the most important layer is the storage/modelling one, which came to be called model layer. on top of that, you need a few other layers but they're really not anything like views and controllers in the GUI world.
the Django layers are roughly:
storage/modelling: models.py, obviously. try to put most of the 'working' concepts there. all the relationships, all the operations should be implemented here.
dispatching: mostly in urls.py. here you turn your URL scheme into code paths. think of it like a big switch() statement. try hard to have readable URLs, which map into user intentions. it will help a lot to add new functionality, or new ways to do the same things (like an AJAX UI later).
gathering: mostly the view functions, both yours and the prebuilt generic views. here you simply gather all the from the models to satisfy a user request. in surprisingly many cases, it just have to pick a single model instance, and everything else can be retrieved from relationships. for these URLs, a generic view is enough.
presentation: the templates. if the view gives you the data you need, it's simple enough to turn it into a webpage. it's here where you'll thank that the model classes have good accessors to get any kind of relevant data from any given instance.
To understand django fundementals and the django take on MVC, consult the following:
http://www.djangobook.com/
As a starting point to getting your hands dirty with ...
"...trying to find some comparable data / architectural models"
Here is a quick and dirty way to reverse engineer a database to get a models.py file,
which you can then inspect to see how django would handle it.
1.) get an er diagram that closely matches your target. For example something like this
http://www.databaseanswers.org/data_models/product_catalogs/index.htm
2.) create an sql script from the er diagram and create the database,
I suggest Postgre, as some MySQL
table type will not have forgien key constraints, but in a pinch MySQL or SQLITE
will do
3.) create and configure a django app to use that database. Then run:
python manage.py inspectdb
This will at least give you a models.py file which you can read to see how django attempts
to model it.
Note that the inspect command is intended to be a shortcut for dealing with legacy
database when developing in django, and as such is not perfect. Be sure to read the
following before attempting this:
http://docs.djangoproject.com/en/dev/ref/django-admin/#ref-django-admin

Categories

Resources