I've googled around for this, but I still have trouble relating to what Django defines as "apps".
Should I create a new app for each piece of functionality in a site, even though it uses models from the main project?
Do you guys have good rule of thumb of when to split off a new app, and when to keep functionality together with the "main project" or other apps?
James Bennett has a wonderful set of slides on how to organize reusable apps in Django.
I prefer to think of Django applications as reusable modules or components than as "applications".
This helps me encapsulate and decouple certain features from one another, improving re-usability should I decide to share a particular "app" with the community at large, and maintainability.
My general approach is to bucket up specific features or feature sets into "apps" as though I were going to release them publicly. The hard part here is figuring out how big each bucket is.
A good trick I use is to imagine how my apps would be used if they were released publicly. This often encourages me to shrink the buckets and more clearly define its "purpose".
Here is the updated presentation on 6 September 2008.
DjangoCon 2008: Reusable Apps #7:53
Slide: Reusable_apps.pdf
Taken from the slide
Should this be its own application?
Is it completely unrelated to the app’s focus?
Is it orthogonal to whatever else I’m doing?
Will I need similar functionality on other sites?
If any of them is "Yes"? Then best to break it into a
separate application.
I tend to create new applications for each logically separate set of models. e.g.:
User Profiles
Forum Posts
Blog posts
The two best answers to this question I've found around the web are:
The Reusable Apps Talk (slides)(video) also mentioned in other answers. Bennett, the author and Django contributor, regularly publishes apps for others to use and has a strong viewpoint towards many small apps.
Doordash's Tips for Django at Scale which gives the opposite advice and says in their case they migrated to one single app after starting with many separate apps. They ran into problems with the migration dependency graph between apps.
Both sources agree that you should create a separate app in the following situations:
If you plan to reuse your app in another Django project (especially if you plan to publish it for others to reuse).
If the app has few or no dependencies between it and another app. Here you might be able to imagine an app running as its own microservice in the future.
The rule I follow is it should be a new app if I want to reuse the functionality in a different project.
If it needs deep understanding of the models in your project, it's probably more cohesive to stick it with the models.
The best answer to this question is given by Andrew Godwin (Django core developer):
The main purpose of apps is, in my eyes, to provide logical separation of reusable components - specifically, a first-class namespace for models/admin/etc. - and to provide an easy way to turn things “on” or “off”.
In some ways, it’s a relic of the time when Django was created - when Python packaging and modules were much less developed and you basically had to have your own solution to the problem. That said, it’s still a core part of Django’s mental model, and I think INSTALLED_APPS is still a cleaner, easier solution than Python’s replacement offering of entrypoints (which makes it quite hard to disable a package that is installed in an environment but which you don’t want to use).
Is there anything specifically you think could be decoupled from the app concept today? Models and admin need it for autodiscovery and a unique namespace prefix, so that’s hard to undo, and I’m struggling to think of other features you need it for (in fact, if all you want is just a library, you can make it a normal Python one - no need for the app wrapping unless you’re shipping models, templates or admin code IIRC)
An 'app' could be many different things, it all really comes down to taste. For example, let's say you are building a blog. Your app could be the entire blog, or you could have an 'admin' app, a 'site' app for all of the public views, an 'rss' app, a 'services' app so developers can interface with the blog in their own ways, etc.
I personally would make the blog itself the app, and break out the functionality within it. The blog could then be reused rather easily in other websites.
The nice thing about Django is that it will recognize any models.py file within any level of your directory tree as a file containing Django models. So breaking your functionality out into smaller 'sub apps' within an 'app' itself won't make anything more difficult.
Related
I'm currently developing a project to store all of my old MP3 files. This project contains multiple applications(Artist, Album, Song) and I'm simply curious to know if it is common for developers to create a separate application which may be named something like 'Dashboard' and use this to host their homepage, login/logout functionality, search features, recently uploaded items, etc. Or is it more common to just stick your homepage into an existing app?
I wouldn't call an approach best practice, however certain practices are commonly used-
core app is created where it's a small project (i.e. probably three or less models and around five views). Dashboard can be a template in this app. You're correct, usually it's common to stick your homepage into an existing app.
account app is created to keep the authentication system separate.
Other approaches are also good.
I am a Django developer with some experience. I am familiar with different best practices and controversial points of view.
Recently, while working on one project, I struggled for a while when I came upon one giant existing app. The issue isn't resolved and I'm still in progress of thinking.
The issue itself: project has a giant application, let's name it "Directory". The application is big and serves to multiple purposes:
1) Provides basic content types for the whole project
2) Provides some helping structure entities (like, Categories, Attributes etc)
3) Handles User Area dashboard views.
4) Handles basic front-end public views.
5) Handles search.
I really don't like how big it is right now. While thinking on possible way of decomposition, I came up with multiple variants. Most likely it'll be the best to do it like this:
I can create a dashboard app, a search app, a frontend functionality app (serves for displaying public content).
The biggest stopper right now is the model layer. The thing is, all of the possible apps mentioned above depend literally on the same models. In my opinion, it'll be wrong to put these models to some of the apps above and leave others without models, as it'll be non-obvious where the mentioned models should live.
The possible solution, in my opinion, will be to create a separate app like "Content Types" or something like that, where I should put these models. But if I do it, I'll come up with apps that:
1) Do nothing but only provide models and admin. 2) Apps that don't have models and only provide functionality (views etc)
So, basically, I'm lost as I'm not sure that app that does nothing has a right to live separately (while the second point is more or less imaginable).
Can anyone please give me possible advice on how should I decompose my app to still follow the django-way of development and have a nice structure? I suspect that the issue I have appeared due to wrong design of the db-layer as well. But, unfortunately, it's too late to save it at the moment and I have to do my best at least with other parts.
EDIT: I'm new to this site but if you are going to down vote me, could you perhaps explain why? I've searched Google, this site and others but have not found anything that makes any sense and I thought this was a site to ask questions and get some help.
I've got a Custom PHP Forum that I am trying to convert to Python/Django as a learning experience and I'm having some problems. I've been reading up on Django and it is encouraged that our application is split into multiple apps. I went through the 6 part tutorial and many other parts of the documentation but I'm left with some questions.
Let's assume that I have about 30 tables.
Tables such as:
posts_index, posts, users, user_groups, user_activity, user_sessions, forums, payment_gateways, payment_logs, etc for a basic forum
I'm having issues structuring my models. With PHP all I needed was index.php, /admin/index.php, view_forum.php, view_thread.php and a few others, everything could pull directly from the database and I had no issues but now I have to deal with apps/modules.
I'm thinking I'd need to structure my apps in a manner similar to this:
/admin/ app
/forums/ app
/view_forum/ app
/view_thread/ app
/forums/view_forum/ app (instead of just /view_forum/, could be a sub app)
/forums/view_thread/ app (instead of /view_thread/, could be a sub app)
My problem and only question here is dealing with global state. For example Users/Group/Session/Logging/Permission information is going to need to be shared across multiple apps through importing in the other apps models file. To do this I need to reference their model information, what is the correct way to handle this?
Would either of these be acceptable?
Create a ton of different apps such as /users/ which would model my users_groups, users, user_sessions, another app for /posts/ that would include models for posts_index, forums, and so forth with these models existing but not actually being used publicly, they would be used in other apps only. They would be imported in areas such as the /view_forum/ app since when viewing a forum I might need to determine if the user is logged in, is a member of a particular group, etc and because of that would need access to a number of the hidden apps and hence would be imported from the hidden app.
What if I just had one single app, instead of it being an app it would just be my entire project. This sounds like the best solution to me but it seems to be suggested if we cannot summarize the entire application into a sentence it needs to be broken up. If I went with one single app being used as my entire project, my models file will have 30+ different models, is this acceptable? I assume not but figured I'd ask.
Do either of the above make any sense? If not what would you do fix it? I'll admit I'm lost so any feedback would mean a lot.
I'm new to Python/Django and am trying to figure things out. I hope I am clear on what I am trying to do. I'm more than welcome to any advice. I've been trying to play around with things but I figure it would be better to ask for advice from more experienced developers. I'm not a professional programmer and am still learning so please be nice :).
I have voted this up... I had similar questions when I first moved to Django (also coming from PHP)
Try not to think of apps in terms of db tables (or url paths), you want to create apps for independent pieces of functionality.
I would say most of your code will be in a single forum app with Forum and Post models in it and all your forum-related urls like /view_forum/ and /view_thread/. Note there's not really such thing as a sub-app in Django... these are different views which all belong to one related set of functionality in a single app.
The 'users' stuff... you normally want to hook in to the Django auth system (https://docs.djangoproject.com/en/dev/topics/auth/default/#user-objects) though if you are trying to keep the legacy database structure this may be harder... you may end up needing your own users app.
The payment gateways stuff sounds like another app again.
For the admin, you get this (almost) for free with Django:
https://docs.djangoproject.com/en/1.5/ref/contrib/admin/
You need an admin.py inside each app, where you register the models that you want to expose to the admin site.
You might find it's best to follow a tutorial and build a simple blog (or try and build a very simple minimal forum from scratch) to get a feel for Django before tackling your re-write. Because trying to exactly recreate the old functionality with legacy db tables will be a bit harder and may lead you into patterns which are not 'good Django'.
You might also find it useful to look at the source code of an existing Django forum app, such as this one:
https://bitbucket.org/slav0nic/djangobb/src/
They have just a single djangobb_forum app that does everything. I think this is entirely justified as a forum is a single complicated piece of functionality.
Note how their Profile model effectively extends the built-in Django auth.User model via a OneToOneField. It makes it easier to integrate with the built-in login and authentication system that way.
Start by integrating your legacy database and then build the Admin site. You'll see how the model information is available to the Admin app and every other app you write. The key is to import models in your 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.
Are there any Django apps equivalent to Drupal's Views and CCK modules?
I find Django much more flexible and logically organized than Drupal. But I think Drupal's Views and CCK modules are killer apps. They let the webmaster very rapidly to build new data models and queries through GUI without touching the code. These modules are very useful for rapid application development. Do you know any similar apps in Django?
Django is a framework, this had been said, but if you look for functionality close to CCK, PINAX makes for python/Django, the equivalent of modules in Drupal, sort of ready to go modules, login/pass check, listing, input output, or CRUDs ect. But in no ways radio buttons and check boxes action programming. You will have to put your building blocks together and indulge some python programming. I found myself spending more time loading extra modules and themes tweaking in Drupal, than putting together a full blown site in Django, maybe because, I own many libraries wrote several times and improved over time, for cases encountered over and over. I focus only on new or cutting edge things. Both approaches are ok as long as you know what you want to go. The hard fact is that for a CMS that want to attract non programmers peoples if you want to build great sites, you have to be good in php/mysql and a good grip on css, and it kind of defeats the purpose. In France we say, "the best tool is the one you use every day". If you are frustrated with Drupal, learn Django, and in the same time needed to master Drupal, you will have a skill to write your own Drupal and others CMS, maybe. Good luck in your endeavor.
I don't think there is something similar and for a good reason. Django is a framework, while Drupal is a full scale CMS. One of the powerful things about Drupal, is how it handles content. Every piece of content is a node, and it lets developers make modules that can add to a node's functionality.
Django is a great tool to, but it's strength is more the ease of development, that lets you create applications very fast. That is what it was built for after all. It would be hard to make something CCK and Views like with Django, and I don't think it would make much sense either. I find that when developing with Django, you can very quickly create most CCK and views things, withe Django models and the orm. You can't do it in a GUI, but that was never the goal of Django. The admin interface also reflects that, as it is good mainly for one thing. Handling content, CRUD style operations. I guess that is why Satchmo created their own settings system for shops.
http://docs.djangoproject.com/en/dev/faq/general/#is-django-a-content-management-system-cms
...it doesn’t make much sense to compare Django to something like Drupal, because Django is something you use to create things like Drupal.
The lack of flexibility that you refer to is the price you pay for CCK and Views. I've used both Drupal and Django to complete major projects. You can use Drupal as a framework too, so in my opinion the two are absolutely comparable.
Django has a way better database abstraction than Drupal, follows more modern programming paradigms like OOP, MVC etc, is more flexible, and Python is just straight up superior to PHP.
...but I still usually use Drupal if either will do. It just gets the job done with less time spent, and works and performs well. Django has nothing like Views, and Drupal's form api is just light years ahead of Django's. Creating multi step ajax forms can be done without ever touching the markup or writing a single line of javascript in Drupal, and presenting dynamic lists to the user can be achieved without even leaving your browser.
Drupal has a much greater deployment rate than Django, not just because of PHP's popularity, but because it actually does some things really well.
My time is precious, and the end user doesn't give a damn as long as my system works.