What does django controllers are in views.py - django

I have followed several django tutorials. I do not know why controllers are stored in a file called views.py. I am confuse with this filename. I am looking for a MVC development. Are there other files in django for "real" controllers ?

The name views.py was a mistake
From an architecture point of view, it was a mistake to call views.py the module where functions receive an HTTP request and produce an HTTP response.
Such module is clearly a controller in the MVC sense. (For comparison, the equivalent functionality in the Spring framework is in a class with annotation #RestController or #Controller.)
Such module is also a REST adapter if you use the Ports & Adapter architecture style (aka Hexagonal architecture).
Such module deals with in-out data (request-response), but it is not a representation of the view displayed to the user. If not, what about an http DELETE endpoint (#api_view(['DELETE']))? What about an http POST endpoint that triggers background processing and has no bearing on what the Web UI shows? The functions in views.py are "handlers" of user actions (i.e., controller in MVC), not the representation of UI data.
I understand that views.py is a convention and you can use other names, but once the tutorial examples and other documentation use that name, it sticks.
Another mistake is when tutorials like this use the name views.py as the single place for all http endpoints. The name views.py is too generic and its very idea is an invitation to violate the Single Responsibility Principle (SRP).
Even simple tutorial examples, should use better names. For example:
if you're handling endpoints that deal with customer functionality, call it views_customer.py or customer_views.py (or better yet, customer_controller.py if you're bold to break with the convention and call it for what it is).

Yes ! Actually it's a design decision and It's described by the guys behind Django Here.
Basically their argument is that, in their opinion,
In our interpretation of MVC, the “view” describes the data that gets presented to the user. It’s not necessarily how the data looks, but which data is presented. The view describes which data you see, not how you see it. It’s a subtle distinction.
a “view” is the Python callback function for a particular URL, because that callback function describes which data is presented.
I entice you to read the entry to get a hold of the overal idea behind the views naming.
About the controllers, Yes again. Mostly though, you can define several layers of the so called Middlewares in django to handle lots of your static logic before/after requests are handled by views, but still, it's the view that plays the main role of a controller in Django.

Look at this logically. What do you normally call a text file with placeholders which is filled with other bits of text by supplying variables? You call that a "template", you don't call that a "view". Only in MVC would you think of calling such a thing a "view".

Related

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

MVC pattern in django

This issue has been tormenting me for a while already. I've read about this topic but nothing seems to clear my thoughts. I understand that they call the views templates, and the models models as well, what I don't really get is where the controllers are. What django calls views seem to me more like actions/methods/functions of a controller than a controller itself, but anywhere I read, I find that supposed view-controller equivalency.
I've worked with MVC frameworks before (ASP.NET MVC3, Ruby on Rails, PHP Laravel Framework), and they all define the controllers as the same thing: a bunch of functions related to a specific topic of the site, namely user accounts or something like that. The best equivalency that I find between this description and django features are the apps, but of course I'm wrong due to the huge amount of people and documentation going the other way.
Could anybody help me with this? Does my mindset make any sense? Am I missing something essential here and then I can't get these concepts right?
It's a mistake to think of design patterns like MVC as unbreakable rules. They really aren't: there are all sorts of ways of implementing them, which comply with the description to a greater or lesser extent.
This is especially the case in Python, where one of the guiding principles is "practicality beats purity" - in other words, do what works.
In any case, Django makes no claim to be an MVC framework. On the contrary, the documentation describes it as MTV: model, template, view. After all, outside the world of design patterns everyone calls "an HTML file with syntax for variables and flow control" a template, not a view.
(That FAQ entry also offers a possible answer to your question: the controller is the framework itself. But it goes on to emphasise that it's a mistake to try to shoehorn into these definitions.)
The views.py defines the view functions for your app and your app groups related functions together.
However what I believe you're missing here is the urls.py.
The urls file is the first part of the controller.
The URL patterns inside urls.py dictates what you're allowed to pass in to the view function or view class (depending on what approach you took, either with function based views or class based views) and then routes it to the proper view function.
So there's tight a coupling between the views.py and the urls.py, that makes up for the entire Controller part of MVC.
Comparing it to Rails, would be that the urls.py is a routes.rb and the actual controller class is the views.py function/cbv.
The mismatch of terminology is unfortunate but more or less doing the same thing.
You can read the Django FAQ. It explains the how MVC is implemented in django. Regarding controller Django has an answer as:
.
Where does the “controller” fit in, then? In Django’s case, it’s probably the framework itself: the machinery that sends a request to the appropriate view, according to the Django URL configuration.
Could anybody help me with this? Does my mindset make any sense? Am I missing something essential here and then I can't get these concepts right?
The only well-defined parts of MVC where nearly everyone had some sort of consensus is the M; the V and C means completely different things in different web frameworks, to the point where MVC framework really only means as not having all your code in one spaghetti (ala typical classical PHP code). You just had to accept that MVC isn't a really well defined term.
Django is not strictly speaking MVC.
I found this discussion very enlightening:
Django is not MVC
Realy guys:
DJANGO is MVC!
But word View use for Controller.
And Django is Full MVC, but
Model - Model
View - Template
Comtroller - View

Application logic in view code

Should I be writing application logic in my view code? For example, on submission of a form element, I need to create a user and send him an activation email. Is this something to do from a view function, or should I create a separate function to make it easier to test down the road? What does Django recommend here?
I found it very hard to figure out where everything goes when I started using django. It really depends on the type of logic you are writing.
First start with the models: model-methods and managers are a good place to perform row-level logic and table level logic i.e. a model manager would be a good place to write code to get a list of categories that are associated with all blogposts. A model method is a good place to count the characters in a particular blogpost.
View level logic should deal with bringing it all together - taking the request, performing the necessary steps to get to the result you need (maybe using the model managers) and then getting it ready for the template.
If there is code that doesn't fit in else where, but has a logical structure you can simply write a module to perform that. Similarly if there are scraps of code that you don't think belong, keep a utils.py to hold them.
You shouldn't perform any logic really in your templates - instead use template tags if you have to. These are good for using reusable pieces of code that you you neither want in every request cycle nor one single request cycle - you might want them in a subset (i.e. displaying a list of categories while in the blog section of your website)
If you do want some logic to be performed in every request cycle, use either context processors or middleware. If you want some logic to be performed only in one single request cycle, the view is probably the place.
TLDR: Writing logic in your view is fine, but there are plenty of places that might be more appropriate
Separating the registration code into it's own function to make testing easier is a good reason. If you allowed admins to register users in a separate, private view, then a registration function would be more DRY. Personally, I don't think a little application logic in the code will do to much harm.
You might find it instructive to have a look at the registration view in the django-registration app -- just to see how it's written, I'm not saying you should or have to use it. It has encapsulated the user registration into it's own function (there's a level of indirection as well, because the registration backends are pluggable).

Alternate URL router for Django

How would you go about using django models and templates, but not the URL routing system? I'd like to swap out the urls.py system for something like PHP where the URL tells you exactly where the code is that's running. Or maybe something more automagic like rails uses -- where the URL always includes the same components like app name, model name and view name.
I just disagree with the line from the django philosophy statement that "Tying URLs to Python function names is a Bad And Ugly Thing." Pretty URLs just aren't all that important to me, and IMVHO not worth the complexity of climbing through a maze of indirection in multiple urls.py files and dozens of regexes to find out what code runs behind a particular URL. It's a personal choice, right? Django is generally pretty modular allowing you to swap out the major components for other ones. So, how would I swap out the part which takes the request URL and decides which view to run?
Are there any alternate URL routers for django out there?
All you need is one line in your urls.py that matches everything, and then just write your handler/dispatcher as a view. That handler does whatever you want based on the parts of the URL....
I've never heard of anyone successfully swapping out Django's URL routing system. There's certainly no hook for it - core.handlers.base.BaseHandler.get_response calls urlresolvers.RegexURLResolver directly. Conceivably, you could add a middleware at the bottom of the stack that dispatches to your own URL resolution system and returns the response, thus bypassing the Django system, but it's a bit kludgy.
If you're after something more like Rails, you might want to try one of the other frameworks - Pyramid, for example, uses a system of Routes very similar to Rails'. Pyramid is much more pluggable than Django, so you should be able to plug in the Jinja2 templating system, which is based on Django's. However, there's no way to use Django's ORM seperately, so you'd need to use SQLAlchemy (which can be used in a way that's not massively different).

Calling small app in template

Lets say I have a website with a small application that lists the 10 newest members, or something dynamic like that. I want this to view on every page, perhaps in a sidebar. How would i go about doing this.
My thoughts on the matter. I might not get the whole django thing just yet, but when I have a url like /foo/ calling a view bar - but what info do I have to send to the template from this view. Does every view have to send the info to the template (just so I can view my app) or is there someway to call this from the template instead.
I have tried to read through the documentation, but its seems I just can't understand this.
The usual way to provide '10 newest members' type of information from other apps is via a template tag. See this article by James Bennett on best practices (although note it's a bit out of date, as it was written before the inclusion_tag and simple_tag shortcuts were available).
Create a template tag that you can call on the page
Create a context processor and inject extra context variables onto each pageload
I'm sure there are other ways of doing this but those are probably the most logical two. The first gives you more power and will waste less processing time (for pages where you don't want to display the data) but a context processor is much more simple to write (you don't have to bend over backwards to please the template_tag gods).
Both are valuable things to know so there you go. Go and learn!
"Does every view have to send the info to the template (just so I can view my app)"
Yes.
"Is there someway to call this from the template instead."
No.
Your views are just functions. Functions can call other functions. That's ordinary good design. You can still do ordinary good design in Django.
You do have the ability to provide a "context". This is still done in the views to provide additional "context" for the templates. See http://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors for writing your own context processor.
Nothing (well almost nothing) is done in the template except render the objects provided by the view into HTML (or XML).
If you have a page that is an amalgamation of stuff from many small apps, then you have two tiers of apps.
Independent Apps.
Composite Apps that depend on Composite or Independent Apps.
Your composite app can call other app view functions to gather data.
Your composite app template can include other app template elements to present that data.
You have all the power of Python to decompose the independent apps into "data production" functions, view functions, template components and final page templates.
An independent app Page will use a view function and a template. The view function will use the data production functions. The template will use template components.
Decomposition still works, even in Django.