Using django models across apps? - django

So in my Django project I have a few different apps, each with their own Models, Views, Templates, etc. What is a good way (the "Django" way) to have these Apps communicate?
A specific example would be a Meetings App which has a model for Meetings, and I have a Home App in which I want to display top 5 Meetings on the home page.
Should the Home App's View just query the Meetings App's Model?
It feels like that is crossing some line and there might be a more de-coupled way to do things like this in Django.

At some point your apps will have to couple in order to get any work done. You can't get around that.

To achieve decoupling as much as possible,
You need to have a Project specific app, that does all the hooking up things between each other.
Using signals from models to create new models in a decoupled apps helps. But doing too much of this, is foolish.

Should the Home App's View just query the Meetings App's Model?
Yep, that's how it's done. If you really want to decouple things, you could make your Home app use generic foreign keys, and some sort of generic template system, but there's not really a good reason to, unless you have grand plans for your home app being pluggable and working with a bunch of other different Django apps.
Writing tightly coupled Django apps is really easy, and writing decoupled Django apps is really hard. Don't decouple unless you have a reason to, and you'll save yourself a lot of work (and happiness!).

If it were me, I would make a template tag in your meeting app that produces the desired output and include that template tag in the home app's template.
That way you are only coupling them in the View portion of the MVC and makes it easier to maintain if you change your models in the meeting app.

For your specific example, I would use a Django templatetag.
Having a templatetag "display_top_meetings" in your Meetings app, and calling it with {{ display_top_meetings 5 }} from your index template, loading it first.
You can read more about templatetags here:
Django Official documentation about TemplateTags
B-List's article on writting 'better template tags'
I hope this help!

yes. I think thats a design feature. All models share a backend, so you'd have to do extra work to have two models with the same name in different apps.
Projects should not share Models

Related

Implementing MVC pattern with Django Rest Framework

I was wondering how could I implement a MVC pattern on a Django Api project, when I start a django project it gives me the apps.py, admin.py, models.py and the views.py , I understand the the models, should be the "M", and the views the "V", but as i'm using the project like an api, the view would be an Angular or React App, so where I put the logical ? Where is the right place to put the "C" controller on a django rest framework project, is it on views.py ?
You need to understand that web service (which you are going to implement with Django) and your client app (which you are going to implement with Angular) are totally different apps and they should not depend on each other. These apps will have their own Models, Views and Controllers.
If we are talking about some business logic that you need to store somewhere on a backend then you can use an approach where you will have an additional level (usually, people call it services.py) and you will import code from this layer to views.py and only call it there cause your views should stay clean and simple as much as possible.
In an ideal case, especially, at the start, I guess, you will not have some tricky logic and mostly your API will look like simple CRUD, so for that case, you even don't need to store additional logic somewhere you just can use rest framework ViewSets as is and store some little snippets in utils.py.
The bottom line is - you don't understand fundamentals that's why you asked the wrong question. And you don't need it right now. Just go and write your app and read the docs about frameworks that you are using, eventually, you will understand this topic.

Moving from PHP/Laravel to Python/Django

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.

Django Sites - Different urls.py for two sites

I maintain a Django webapp for a client of mine. We built it out in Django and for computer users, it's great. We now want to cater to mobile device users.
On top of a template switch, we also need things to work differently. The application will have views that work in a subtly different way but also the URL structure needs to be simplified.
I realise what I'm about to ask for violates the DRY ethos but is there a good way to split the urls.py so that half of it is for ourdomain.com and the other half is for m.ourdomain.com? If I can do that, I can add a mobile_views.py and write the new views.
Django's Sites is enabled in the project but I'm happy to use a hard-coded request.domain.startswith('m.')-style hack. Seems like that might perform better - but I've no idea how one gets the request from the URLs file.
Use middleware to detect the access to the other site and set request.urlconf to the other urlconf that you want to use.

Django deploying as SaaS (basecamp style)

I am almost done developing a Django project (with a few pluggable apps).
I want to offer this project as a SaaS (something like basecamp).
i.e: project1.mysaas.com , project2.mysaas.com etc
I seek your expertise in showing me the path.
Ways I have thought of are:
1 use Sites to define site specific settings.py
2 a middleware to detect request then set settings accordingly
3 create Django project (taking in pluggable apps) for each site
Thanks.
btw, i am a total newbie.
Your requirements aren't at all clear but I'll assume you aren't doing anything tricky and also assume your "project1", "project2" are customer names which won't need any special branding.
First, about your ideas:
You probably won't need to use the sites framework unless each site is branded differently. The site framework works well doing what it was designed to do, which is present different views of a common set of data.
This would work but probably is not the best approach IMO.
This is unmanageable.
Now, this is a really hard topic because there are so many issues. A decent place to start reading is the High Scalability Blog and especially relevant for you would be the post on 37signals Architecture.
Finally, here's what I am doing in a small SaaS app (that doesn't need extreme scalability):
Use the sites framework (because user pages will be branded by the partner/reseller and each partner has a unique login page)
Use mod_wsgi to minimize resource usage from all the Django instances.
Instead of middleware I put a common code at the top of every view that identifies the company of the user. I need this for logic in the views which is why I don't think it's useful in middleware.

Creating an entire web application using django admin

I was thinking that django admin is an utility to provide trusted administrators of the site, full access to the site's data model.
However, after going through django admin in detail, I understand that it is very powerful set of views and templates that one can use to create an entire application.
How often do you create an entire application using admin alone? Is it easier to create using views itself than customizing admin that much?
How about building prototype using admin. Do we even need to build prototype? The admin customization cannot be re-used in real application.
If I want to use a part of the admin code in real application (with different templates), is there some kind of scaffolding option available?
"The Admin is not your app."
If the customization goes beyond the trivial, write your own views.
In my experience, I leave the internal admin pages relatively untouched. Instead, I override the admin index template, where I put links to custom-written views when the user needs to do nontrivial reporting or form handling.
I have done something like that before. It was a CMS for a university completely implemented by extending Django admin. It turned out it was a bad design descision. I had to jump through hoops to do some things.
It really depends on what the requirements are for your application. If there needs to be lots of ajax or some specific workflow extending the admin will not be the right thing to do. But I think 60% of cases can be covered by extending the admin.
It's also excellent for building prototypes.
EDIT
OK, that was in the 0.96 days.
So far I've built 2 "big" sites that are in production completely on top of the new admin. These are mostly case management, data entry and reporting so they could be squeezed into the workflow of the admin. But, not without a big effort going into extending the base Site, ModelAdmin, InlineModelAdmin etc. The decision to go this way is we were pressed to do it quick. But in the first case it was a perfect fit for the requirements too. Both run on an intranet in the government sector. Both do their job fine. One with 200 tables handling tens of thousands of entries. The other one manages payments.
So, yes it's true. The admin is not your app. However, it's extendable enough although much of it is not documented. And it fits in most basic enterpresey workflows. So it's worth considering in a limited number of scenarios.
I disagree with most of the other answers.
Simply put, there is no match for what you get for free using the admin app.
Your first customization of the admin will be tough as you'll be facing a steep learning curve (you will need to deal with overriding templates, Managers, ModelAdmins, probably use database views, the CSS and JS, some additional forms and validation rules, etc...). But once that is done, you'll start to feel king in bending the admin system to your needs. I have built a complex inventory and accounting web application with data-entry, reporting, and permission system all based solely on the admin interface and back-end.
The Django Admin is incredibly flexible and can be overridden in multiple ways. Unfortunately there is more than one way to do the overriding and some of the techniques are not terribly well documented.
The good news is that the following strategy seems to work well:
Override, customize and subclass the admin app until it all starts feeling a little painful and at that point just drop into your own views where needed.
There's some useful links in my answer to this question
In short:
Try out the admin part for your needs. Modify the standard views. If there is something missing, you can always develop your own view.
For me, I can't imagine an entire (bigger than rolodex) application based only on django-admin.
A.