django - when url namespace should be used? - django

I mostly read that it should be used with 3td party apps. But if I have my own many local apps, does it make sense to give each its own namespace?
This way I can know which url belongs to which app. Rather then relying on "name "solely.

Typically namespacing would be useful if you need to reuse the apps (e.g. make a part of your app a module that you'd use in another app), or build sites that contain multiple apps (e.g. two projects sharing the same user database). Another case is if you want to keep specific features of your project well-separated, you could make them into separate apps with their own namespace and their own urls.py.
There may be a few cases, if you're using incorrectly namespaced apps as modules of your own app, where there'd be conflicts.
Namespacing urls.py isn't the only thing you should do to reuse apps: You may want to put all your templates and static files in subfolders, as the way they're collected flattens the structure. e.g. your templates would be in my_project/my_app/templates/my_app/template.html
If you are certain that what you are developing will be standalone, there may be no need for namespacing.

Related

Create a separate app for my REST API or place it inside my working app?

I'm building simple gis system on geodjango.
The app displays a set of maps and I'm also attempting to provide a RESTFUL API for these maps.
I'm facing a decision whether to create a separate app for the API or to work inside my existing app.
The two apps are logically separate but they share the same models.
So what is considered better?
Although a case can be made for either of the approaches, I think keeping the APIs inside their associated apps would be a better one. Since the code in APIs is going to depend on the models, or other utility methods anyway, keeping APIs in the same app would lead to more cohesive code. Besides the very ideology behind Django apps is that they can be isolated and reused.
There used to be a similar case with storing the templates. In the initial days of Django, people used to prefer to store all the templates altogether in the same global folder (with subdirectories by the names of the app), however, in recent times even Django has started discouraging the said approach in the favour of storing templates in the respective app itself.
#hspandher's answer is very solid and will allow for most of your needs to be implemented.
There is though another approach which may be a bit more complicated to achieve but gives you all the space you may need for experimentation and reusability potential:
Separate everything:
Backend:
Isolate your API from its visualization (see frontend below) and make it completely autonomous and self-contained.
That can be achieved by separating your apps inside your Django project and expose the corresponding APIs which must be the only way for an external factor (ex. client, another app etc.) to "talk" with any one of your apps.
Frontend:
Assuming that you have your APIs exposed, you effectively separated the visualization from the logic and therefore you have many options on how to visualize your maps.
For example, you can now build a React app which can make requests to your API and visualize the responses by using any of those tools: leaflet.js, D3.js, or anything that you like really.
Summary:
The benefits of this separation are:
Separation of logic and implementation.
Better maintainability.
Many tool and technology options to use.
Reusability.
As a side note, you can read about 12 factor method and think about using it in your implementation.

django best practice for use different project using both some models

i need to create 2 project a little related.
i need to use for both project some apps and models. and maybe the same settings. using different templates and domains.
can do you recommend me?
Depending on how independent your projects are, there are two different solutions.
As karthikr reccomended, there is the sites package. If what you have in mind is really multiple projects that are very similar, but with different content and templates depending on the domain or URL, this is what you are looking for.
If what you have in mind is creating apps that you can reuse in multiple different projects, think about "reusable apps".
Python, and hence django, is inherently modular. This means that it is really easy to create and use apps, and to import them whenever you need them. Have a look at django's documentation on reusable apps:
https://docs.djangoproject.com/en/dev/intro/reusable-apps/
For some useful advice on app design and re-usability, have a look at James Bennett's (old but not completely outdated) talk at DjangoCon 2008: https://www.youtube.com/watch?v=A-S0tqpPga4

integrating third-party django apps and templates

I'm new to Django and fairly confused about how third-party apps are best integrated. In my (possibly naive) interpretation of DRY, I want to minimize copy/pasting not only my own code but other people's code as well, so I'm happy with, for example, the pattern of using contrib.auth as mostly a black box if I needed additional info on auth.User (by extending auth.User with a UserProfile object or inheritance). And this was how I imagined I'd use most third-party apps as well.
However, I quickly found out this was very difficult, so now I've resigned to having "copies" of all of my third-party apps living inside my project folder that are basically entire copies with minimal changes. The final straw was me wanting to add a basic blog (I settled on django-basic-blog) and needing to just change a single template, and I thought of no better solution than just making a copy of that app inside my project with the single template changed.
My questions:
in this specific case where I need to change just a single template, is this (copy the entire app over) the best I can do? If I just needed to change a single model I can keep the third-party app respectfully intact and do a model inheritance in my own app...
in general, this practice of copying the apps under my project and patching each a tiny bit feels crazily wasteful and dirty. It also feels like if I'm using a frequently-updated third-party app it will be a pain to sync the changes. Should I just learn to love the bomb or is there some obvious architectural pattern / Django-provided assistance I am missing?
You should not modify the code of 3rd-party modules, as it's hard to track the changes and it creates a mess with the same code copied into many projects. Typical solution is to have only one version of each third-party module in your python path, not in your project's dir. This single package can then be reused by all of your projects.
However different approach is needed for templates, as they often need to be modified on a per-project basis. That's why Django comes with settings.TEMPLATE_DIRS and settings.TEMPLATE_LOADERS.
TEMPLATE_DIRS specifies list of directories containing template files. TEMPLATE_LOADERS specifies the classes used to load templates. The loaders will be used in order they were defined and the directories will be traversed in order they were defined. So you can look for templates in your project's directory first and in other modules as a fallback.
So basically you do not need to copy the entire python module in order to change one template. Copy just the templates directory of that 3rd party module or even just the single template you want to change. If you'll put in the right place and add have the path in TEMPLATE_DIR Django will use it.

Is splitting a large django app a good practice?

I have created a complex E-R diagram for a django site I'm developing. It maps to 11 tables in the database. The site has many features, so I would like to split it into multiple apps. The Django manual said that Django apps should be pluggable, but if I split the models into many apps, they would be dependant on each other. Is this a good practice? If not, how should I structure my application?
Thanks
I wouldn't worry over the statement about making apps pluggable. Sure, if it could be a useful app in other projects, you may want to - but nothing enforces this.
There is no harm in making internal apps dependent.
Personally, my project-specific apps live inside the project module (or for larger projects, inside a project.apps module). This way, you're not polluting the python import namespace with your one-time apps.
You could separate them out into self contained apps, and they would work within the context of your project.
You could also create each app so it's totally independent. This often takes a bit more work, a nice example of this is Django-tagging, which you can basically attach to any other object.
So yes, you can do it. However if the app is just for you it may not be worth the effort (IMHO) ;)

django -- application subdirectory site/app1/app2/app3

If you were to write an app for a site, but wanted to make the app plug&play so you can just drop it in any Django project, set the main URL and there you go, how would you do that if you wanted to keep all the other required utility apps included in your portable app.
Example:
site/
site/site-app1
site/templates/site-app1
site/util-app1
site/util-app2
site/util-app3
Note: that the site-app1 makes the use of all three util-apps. It works great in this manner. But now, you decide to send the app to someone, but just that app with all its dependencies.
If we could package and send the apps like this?:
site/site-app1
site/site-app1/template
site/site-app1/util-app1
site/site-app1/util-app2
site/site-app1/util-app3
Then you just send site-app1 and everything goes with it.
Is there a way to make portable with utility apps as subdirctories?
Note: the idea is that we don't want to send the whole project, but one site-app within
the project only.
There have been a few presentations about reusable django apps, so search around. These should get you going:
Developing reusable apps. pdf and video
Django Templates: The Power of Inheritance
The presentations #Gerry links to are good sources of general info. To answer your question more directly, there isn't a way to package one app inside of another one (EDIT sorry, this is just plain wrong. You can put one app inside of another one's namespace, and it works just fine. It's an odd thing to do though: you're implying that the one app is a part of the other one; if that's true they'd be easier to use as a single app. So I'd still recommend one of the below options). AFAICT your options are:
If possible, make those external dependencies optional (i.e. enhanced functionality if util_app1 is available, fallback behavior if it isn't). This is how many apps behave with respect to, say, django-tagging or django-mailer.
Roll all the functionality into a single app. Depending how much code you actually depend on from the utility apps, if the dependencies are absolutely necessary for your app to function, this might be the best option to make things easy on your users.
Package and distribute all the apps separately and note the dependencies both in the documentation and in the setup.py install_requires. If all the apps are independently useful, this approach may be best. If they aren't all independently useful, why are they all separate apps?
Django applications can be made portable by adhering to certain practices. Ofcourse, these are not mandated
Application Location
The convention is to add applications in an apps/ directory, and to modify the manage.py (and eventually the apache config) to include
import sys
from os.path import abspath, dirname, join
PROJECT_ROOT = abspath(dirname(__file__))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))
Your directory structure will look something like
site
site/apps/
site/apps/app1/
site/apps/app2/
Templates
Templates are located in the templates directory in the application. The convention is not to force the user to copy them in any other location. Eventually the user can have global templates to override the ones in the application.
Settings
Keep all default settings in a local file within the app directory. The settings would be overridden by the global settings. The local settings file will have the following structure..
from django.conf import settings
def get(key, default):
return getattr(settings, key, default)
SETTING_1 = get('SETTTING_1', 10)
These conventions should cover most major issues.