Django project applications division - django

I'm currently writing django project and got confused when it came to separation into apps. Project consists of posts and categories which are kept in one app, also there is a 'main' app which handles user profile view, login, logout and registration. Now I'm trying to implement user-to-user messages and I'm wondering if it should be kept as separate app.
If Message model is kept in application 'messages' how do I realize show_messages view?
1) It seems that it should be stored in 'main' app since it's linked by my_profile view. It would just get all Message instances form 'messages' app and render template extending profile.html or including from 'messages' app a partial template responsible only for messages listing. But why would I then need separate application just to hold one model there with some helper functions?
2) Secondly I wonder about placing show_messages view in 'messages' app but then I would need to use template which extends template from other application which again seems to be violation of self-containment rule. Also all "accounts/" urls are currently kept in main.urls so I feel wrong about adding "accounts/profile/messages" rule to messages.url.
3) Finally I think about moving Message model with all helpers and templates to 'main' app since messages are designed to work with User models and views therefore forcing additional separation seems useless.
Thanks for reading my thoughts, I'll appreciate all clues and explanations.

When I first started working with Django, I found the answers on this SO question to be particularly helpful, regarding app/project layout: Projects vs Apps
Many of the answers are useful, but this one is particularly pithy:
Try to answer question: "What does my application do?". If you cannot answer in single sentence, then maybe you can split it to several apps with cleaner logic?
I've read this thought somewhere soon after I've stared to work with django and I find that I ask this question my self 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.
Interdependence of apps isn't always problematic. For example, in a lot of my projects I have a separate app that is used solely for creating dynamic menus. In order to work properly, I need to import the specific models of that site into that app -- so I couldn't just drop it into another site, unaltered, and expected it to work. Nonetheless, the other 90% of the code in that app is completely reusable, and it's easier for me to move the relevant code to a new project if its already spun out into a separate app -- even though that app only holds a templatetag and a template.
Ultimately, a django site would technically run just fine with ALL models/views/etc in one big, unwieldy app. But by breaking your project down into "this app performs this specific function" you're probably going make managing your code a lot easier for yourself.
Regarding the 'url' point in 2, there's no reason not to subspace URLs. You are already doing this in a django project already -- mostly likely your main urls.py has an include() to another app, such as your main.urls. There's no reason your main.urls can't also have an include() to your messages app.

Related

Multiple reset passwords in django

I have a project which have a personal app, where the login takes place, and a question app which also includes a profile page. I have managed to reset pasword from the login page, but when I try to do the same in the question app (using different templates, because I do not want the same on these pages), it just goes directly to the login reset template.
I thought it would be enough to just add a new registration folder in the questions app, but it still goes searching in the personal app I think.
Is it possible to just fix this using the django auth views or do I have to create my own views for the questions app?
You will need to create separate views, as well as separate templates.
First, make sure that you understand the User model, and how authentication works in Django. The core docs have plenty of information on that.
Second, look at what you are trying to do and create a view specifically for the template you are creating. Make sure that view processes the data the way that you want to, and that it redirects where you want the user to be redirected to after making the update.
One question to ask yourself though, before you go through this trouble is "Do I really need to have two places to do this?"
Having more than one location to handle password resets is not likely to end up being what you actually want in the long run. I would personally keep all of the account manipulation views in one place so that you don't mess something up if you decide to change something in one place and forget in another.
Two principles that are important when developing any kind of site are KISS and DRY. KISS is just the traditional keep it simple.
DRY means don't repeat yourself.
Unless there is a NEED to have the code be in two different places, it is a bad idea. ESPECIALLY with account related things.

Django: Since it is not strictly MVC, but MTV, what is "view"? [duplicate]

This question already has answers here:
MVC pattern in django
(7 answers)
Closed 9 years ago.
I'm new to Django and I read two somewhat contradictory things about it. One source says that it is based on MVC (Model-view-controller) style, other argues that it is MTV (Model-template-view). I understand it as MTV. Am I correct in my view? No pun intended.
If it is, I'm still confused by the two notions of "view", since they are different in two contexts.
Django documentaion says:
A view is a “type” of Web page in your Django application that generally serves a specific function and has a specific template.
To me this sounds like the view is a function-with-template.
Does anyone have a clear understanding of the situation? And a good, the simpler the better, explanation. Maybe some analogies?
I think you are getting confused by patterns and styles and analogies and acronyms.
Django has a file named urls.py, that maps incoming requests to views. A view is a function (or class implementing some methods) of which the return value (a HTTPResponse, usually) is sent back to the browser. Often, but not necessarily always, views use templates to make that return value.
Django also has an ORM layer (a mapping between Python classes and database tables), and such classes representing database tables are called "models". Views often need information from the database, and they call functions on the models to get it.
Another core part of Django is the form handling. Views often need to get parameters from the request (like from submitted forms) and they use forms for that.
And that's Django. If that is obviously some acronym pattern to you, feel free to consider it that...
Views are the places where we use to write the Business Logic. Business Logic can be written anywhere in the project but it is suggested to write it in the views.
A view function, or view for short, is simply a Python function that takes a Web request and returns a Web response. This response can be the HTML contents of a Web page, or a redirect, or a 404 error, or an XML document, or an image . . . or anything, really. The view itself contains whatever arbitrary logic is necessary to return that response. This code can live anywhere you want, as long as it’s on your Python path. There’s no other requirement–no “magic,” so to speak. For the sake of putting the code somewhere, the convention is to put views in a file called views.py, placed in your project or application directory.
Go through the docs for a much clear idea.
https://docs.djangoproject.com/en/1.6/topics/http/views/#writing-views

Django - using different apps together in a project

In the basic Django tutorials and documentations I have found so far, apps are treated as some standalone parts of the project.
I haven't yet found, though, solutions of using them together in a complex project.
We can sign up at some url domain/signup, and it is handled by users.views.signup.
For a GET request signup renders signup.html.
For a POST request, after evaluating the posted data, it either
renders signup.html with some message or registers a new user,
logs him/her in and redirects somewhere.
We can create a new post at domain/new_post (or domain/user/new_post), which is handled by posts.views.new_post. It acts similarly to the signup handler:
For a GET request it renders new_post.html.
For POST requests it evaluates post data and then either renders
new_post.html with messages or registers the new post and redirects
somewhere.
A general website is built up of several apps, and the webpage displayed for a request at some url offers functionalities from several apps.
For example, after logging into some popular social site, we can create new entries on our wall, search users (it is normally a wider search, but for sake of simplicity, let's only deal with users), also ads and our friends may be listed in the sidebars.
How are these parts built up from the different views and templates of the different apps?
To make the question more specific:
For a GET request received at some url, how can we display
user-search-form, new-post-form and friends-list together?
If we do that by some project-level common view, what about the app-level views?
I have read that the {% include %} tag is handy for building template from several "subtemplates", but what about the different variables the included templates take?
How can we handle user-search-related GET requests, and new-post-related POST requests that may be sent from the same url?
(The expression "requests sent from urls" may be inappropriate, but the user may send the different requests by acting on the page displayed at one specific url.)
Also, the different components should be kept decoupled.
Note: this question may be too generic for SO, so instead of detailed answers I would also appreciate sources, possibly with examples of using different apps together "in action".
For a GET request received at some url, how can we display
user-search-form, new-post-form and friends-list together?
You can request to render any template from any view. Django will search for the template through every registered app for a template directory. Or you can specify your own template directories using TEMPLATE_DIR, but it seems like you already knew this from your next question....
If we do that by some project-level common view, what about the
app-level views?
Could you please try to explain this question in more depth?
I have read that the {% include %} tag is handy for building template
from several "subtemplates", but what about the different variables
the included templates take?
From the docs:
An included template is rendered with the context of the template
that’s including it.
If you have a partial template, intended for including, like:
# hello.html
<h2>Hello {{ person.name }}</h2>
and another template is including it:
# greeting.html
{% include 'hello.html' %}
render_to_response('greeting.html', {})
the output will be Hello because you do not have a person in the template context
I don't quite understand your second bullet point. Your django package is just a python package. If you had two apps you can import code any way you choose, importing modules from your two different apps.
For example, in most projects I end up having a common app. This usually contains utilities used throughout the whole django project. It usually contains my base test classes.
In your apps you can just import
from yourproject.common.utils import a_function
To help with decoupling django provides a signals framework. Your apps can emit and receive signals.
Django includes a “signal dispatcher” which helps allow decoupled
applications get notified when actions occur elsewhere in the
framework. In a nutshell, signals allow certain senders to notify a
set of receivers that some action has taken place. They’re especially
useful when many pieces of code may be interested in the same events.

how to make interaction between different django apps in a single site?

I have just learnt about Django apps. I want to know that within one site, if I make different apps. like, users, profiles, polls, blogs,comments, jobs , applications then how can I manage them to make them intereactive? And is it how the concept of app should be? I want to have things loosely coupled that's why asking? Rails work on the way of REST, so do Django support that also with the use of apps? May be my questions seems a bit ambiguous because I am new to django and some of my concepts are still messed up.
Please tell what ever you know.
The general idea is that apps should be as loosely coupled as possible. The goal is to have completely self-contained functionality. Now, of course, that's not always possible and many times it even makes sense to bring in functionality from another app. To do that, you simply import whatever you need. For example, if your "blogs" app needed to work with your Comment model in your "comments" app you'd simply add the following to the top of the python file you're working in:
from comments.models import Comment
You can then use Comment as if it were defined right in the same file.
As far as REST goes, Django's views are much more fluid. You can name your view whatever you like; you need only hook it up to the right urlpattern in urls.py. Django views can return any content type, you just prepare the response and tell it what mimetype to serve it as (the default is HTML).

Avoiding circular dependencies in Django applications

While working on my Django-based projects I'm always trying to follow Django's approach to reusable apps - I'm trying to decouple my applications from each other and especially trying to avoid cross references but sometimes it does not seem to be possible.
Let's consider a simple example with 2 applications: articles and users. Articles application defines article model, articles list view and single article view, users application defines user model and user profile view. Article is referencing user from the author field, so articles application is obviously dependent on users application which is fine.
But when it comes to user profile, I want to display latest articles authored by the user (and may be latest articles viewed by the user) on that page but that makes users application aware of articles application which is what I'm trying to avoid.
I can obviously try to push all such references to the template level but it still does not solve the issue completely and at the same time may be very inefficient in terms of database queries sometimes.
What do you guys do in such cases?
If you are really set on not having any conversation between the 'user' app and the 'article' app, then you need a third app to act as interface. That would know about users and articles and define all the coupling between them. Your article view would be in there, since it has to get the user data, and your user profile view would be in there, because it needs to say "Fred wrote 5 articles".
Whether this level of decoupling is worth it, I don't know. Sometimes programming for re-usability gets in the way of making the thing usable in the first place.
The standard (or preferred) way of keeping coupled apps decoupled is to add a conditional coupling - like in some apps that try to import django-notification and only if they find it, they report events to it.
Still, if you have two apps that talks to each other by design, then I don't see any point in decoupling them - there are plenty of examples in Django world of apps that just require other apps. Note that I'm talking here about writing real-world software, not about some academic delibrations :-)
It seems that in this case, the dependency of users on articles is in a method, not a field. (Whether it's a model method, a model class method, or a manager method is immaterial). If that's so, you can do a lazy import of articles inside the method. By the time this import is performed, users.models will be fully loaded, so even if this is a circular import, it will not cause problems. The "import users" statement in articles will not have to re-load users and will have the full users namespace available.