I want some clarity. I want to learn more about django and use it as replacement for php/laravel. But the default structure and convention of django confuses me a bit.
My PHP/Laravel project has 3 parts:
- Administration
- Core (Web app for regular users)
- API Service (REST-API for mobile apps)
However all of controllers, models and views are contained in a single Laravel application. I separated Auth, Admin, Api controllers into their own folders/namespaces.
One thing that confuses me is the default Django structure 1 view 1 model file. How should i go about reworking this application in Django should each of my controllers be a separate app in my django project or should I have same approach as in Laravel. 3 Django apps in one project one for admin one for core and one for api ? Where should I keep my models than since in Laravel all models are used by all 3 parts ?
My current structure:
./
./controllers/
./auth/
LoginController.php
RegistrationController.php
...
./admin/
ReportsController.php
UserController.php (Admins overview of all users)
...
./api/
HealthController.php (API CRUD for Health resource)
ExerciseController.php
HomeController.php
UserController.php (Regular users profile page CRUD)
...
./models/
User.php
Health.php
Exercise.php
...
One thing to remember about Django is that an app in Laravel doens't necessary translate to an app in Django. In Django, there are projects, and each project can have any number of apps. For example, I have a "Backup Admin" project where I manage a lot of the day-to-day issues of managing a tape backup environment. I have an app for media (that has 3 models, one for regular media, one for cleaning media, and one for media that we want to exclude from tape ejections). I have an app that represents the backup images, and another for backup jobs (to check status codes). Each sub-piece of my project goes into another app.
If I wanted to do another Django project that had nothing to do with backups, I'd make that a completely separate project, which would have a separate directory structure from my backup project. It'd have it's own urls.py, settings.py, etc.
Regarding the models piece, I put all of one app's models in the same file. For example, in my media app, I have models.py, which contains all three models that I mentioned above. This is completely optional, but I do it just so while importing these models into other parts of the project, I don't have to remember what the file names are, instead I can just do this:
from media.models import CleaningMedia,Media,EjectExclusions
Otherwise I'd have to have 3 different import statements if they were in different files. It's completely possible, but based on your preferences.
Regarding the controller, Django lets you do it either way. You have a project-wide urls.py file that you can use to control all of the traffic, or you can have separate urls.py files in each app to control that app's traffic. I prefer a single file, but that's just me. Personally if you have a lot of controller entries, you should probably split them up into app-specific urls.py files, just to keep it clean, but again, either method would work. I think of maintainability (especially with respect to teammates having to support it) when I make these types of decisions.
The admin interface is built-in, so there's not really an app for that, but you can decide which models and which apps have entries on the admin interface quite easily. Each app has an admin.py file that controls this.
A side note, for a RESTful API, you also might want to consider Django Rest Framework. It's a great piece of software, and the documentation (and tutorials) are very helpful.
Edit:
The 1 view/1 model thing again is just preference. You can have as many files as you want. The only trade off is when you import them into other files, you have to specify the file you're importing it from. That's really all there is to it. I know people who have a views/ directory, and inside there, have separate files for each view, keeping each class/function separate. Totally a matter of preference.
Related
Is there a way to deploy Django Admin and your main application separately, though both of them sharing the same Models / Business logic services.
I come from Grails background where you can create a plugin which can hold your Entities and common business logic and that plugin can be utilized by other application deployed and scaled separately though using the same Database. You don't have to repackage your plugin again for every change rather its just sibling folder to your other projects.
Can I achieve something similar with Django?
Assuming a typical setup, in order to be useful Django Admin needs access to project's apps and their models.
So a setup that you've described would require at least:
simple URLconf with just Django Admin
models and their Admin bindings for all apps that need Admin
settings with database credentials
Even if your models and Admin bindings are not dependent on other parts of the codebase,
extracting the above components to a separate project and then keeping everything
in sync sounds pretty hard.
Summarizing: I would say it's hard but possible if it's something that you really need,
but Django Admin hasn't been designed with such use case in mind.
Django admin is actually separate from the main application by placing it on its own url. Even if they know the admin url, users cannot log in to the site's admin unless they have already been assigned Staff status via the admin. You can set the admin prefix to anything you want, so if you want to "hide" the admin login page, just make it something long and random (good for security too), and basically no one but those you tell will even know where the admin site can be found.
The basic Django app contains models and views, however, this structure seems not enough for a complex web app. How can a designer accomplish a certain level of modulation with Django?
A complex web app can consist of many different Django apps. A Django app is basically a module centered around a set of URLs and/or models.
Besides that, it's all just Python. You can split off business logic code to any Python modules you want, put views in any modules you want, and turn models.py into a models/ package with submodules (as long as the package's __init__.py imports * from all the submodules, I think).
A Django project will often consist of many Django apps
When you start to build a "web app" with Django you are creating a project... inside this you will structure your code into one or more Django apps specific to your project. You will likely make use of a number of 3rd party reusable Django apps as well.
See the tutorial:
https://docs.djangoproject.com/en/dev/intro/tutorial01/#creating-a-project
I want to add Django Sessions to my Django Admin, and I am following an SO post about this, but it is unclear where I store this code. Do I put it in an admin.py file? Under what directory?
In short, it doesn't matter. You can put the code into any of your apps' admin.py files. However, in situations like these I tend to use a generic app in my project, usually named something like utils, that exists for the sole purpose of housing code that doesn't belong to one specific app or could be used by multiple apps.
If you want to be more specific, you can create a sessions app in your project specifically devoted to this code and any other code related to session management for your project, or perhaps an existing app that is somewhat related. For example, I put customizations to the User admin in my accounts app that holds the UserProfile model.
I am developing a business directory website, and it has
Home page
Search Result page
Listing page
I am currently at the design stage and someone suggested to separate the pages/functions into different apps, eg.
home
search_result
listing
Is this the best practise in the Django community? Or what would you do?
No. These sound like different views within a single business app.
You definitely don't want a new app per DetailView, ListView, or SearchView. That would quickly become confusing...
Think of what the app structure actually does: it adds database database table prefixes (appname_), splits models.py files and encourages its own views.py file and tests.py file.
The differences between the home, search_result, and listing views don't justify the above in my opinion.
If you want a directory/file structure that separates your distinct views, you could build a views directory in your app which contains individual search_result.py views... if they are long.
I am new to django and python and am trying to figure out how to modify an existing app to run multiple shops through a single domain.
Django's sites middleware seems inappropriate in this particular case because it manages different domains, not sites run through the same domain, e.g. : domain.com/uk domain.com/us domain.com/es etc.
Each site will need translated content - and minor template changes. The solution needs to be flexible enough to allow for easy modification of templates.
The forms will also need to vary a bit, e.g minor variances in fields and validation for each country specific shop.
I am thinking along the lines of the following as a solution and would love some feedback from experienced django-ers:
In short: same codebase, but separate country specific urls files, separate templates and separate database
Create a middleware class that does IP localisation, determines the country based on the URL and creates a database connection, e.g. /au/ will point to the au specific database and so on.
in root urls.py have routes that point to a separate country specific routing file, e..g
(r'^au/',include('urls_au')),
(r'^es/',include('urls_es')),
use a single template directory but in that directory have a localised directory structure, e.g. /base.html and /uk/base.html and write a custom template loader that looks for local templates first. (or have a separate directory for each shop and set the template directory path in middleware)
use the django internationalisation to manage translation strings throughout
slight variances in forms and models (e.g. ZA has an ID field, France has 'door code' and 'floor' etc.) I am unsure how to handle these variations but I suspect the tables will contain all fields but allowing nulls and the model will have all fields but allowing nulls. The forms will to be modified slightly for each shop.
Anyway, I am keen to get feedback on the best way to go about achieving this multi site solution. It seems like it would work, but feels a bit "hackish" and I wonder if there's a more elegant way of getting this solution to work.
Thanks,
imanc
There's no reason you can't the sites framework with multiple Django installations served from different subdirectories under the same domain.
OK I have done some further digging and it seems that the Django sites framework is not suitable for the same domain but with different paths:
www.mydomain.com/uk
www.mydomain.com/au
etc.
The two other options are an apache/wsgi set up where a separate wsgi and settings.py is referenced for each subdirectory. This seems a bit cumbersome; I don't really want to have to be reconfiguring apache each time I deploy a new shop. Also it'd make maintaining the local dev, online dev, staging and live versions of the site more hassle.
I think given this situation the best solution is to look at a middleware class that keeps track of country code and somehow changes database settings and root urls.py. Then each app is going to have to be aware of its current base url for things like form actions and links and so on.