Django for Designers/Basic views: Difference between revisions

no edit summary
imported>Paulproteus
(→‎M-V-C separation concept: Make the image not link)
imported>Aldeka
No edit summary
Line 21:
[[File:mtv-diagram.png|400px|Django architecture flowchart|link=]]
 
<div class="instructor">For Django, a ''model'' represents how the data is stored. This is the part of your app that ties your data to storage in a database. You write Python code, and Django converts it and out of into SQL, the language spoken by databases.
 
A ''view'' in Django handles a ''request'' from the website visitor for a web page. What you do with this request is up to you, and is the domain of the view code that you write. For example, when a request comes in, you could send start a background process to send a fax to Tokyo indicating how happy you are that someone came to your website. Or you could provide a HTTP response to the website visitor with a list of recently bookmarked web pages if you are providing a bookmarking app.
Line 27:
The ''templates'' in Django control how data is presented. Typically, a view provides a collection of data to the template. The template then might loop over that information, wrap it in HTML bulleted lists, wrap ''that'' in a standard layout for all pages across your site, and serve that out to the site visitor. The templates usually refer to some ''static'' content, such as CSS, that makes the site actually seem designed!
 
Keeping this separation in mind is essential to feeling at home when using Django. (And since most web programming frameworks work via a similar separation, this mindset is good to keep in mind generally.)</div>
 
=== Writing our URLs ===
Line 34:
 
When a user requests a Django-powered page, the system looks at the ROOT_URLCONF setting, which contains a string in Python dotted syntax.
Django loads that module and looks for a module-level variable called urlpatterns, which is a sequence of Python tuples in the following format: '''(regular expression, Python callback function [, optional dictionary])'''
 
Django starts at the first regular expression and makes its way down the list, comparing the requested URL against each regular expression until it finds one that matches.
 
<div class="instructor">You might ask, “What’s a regular expression?” Regular expressions, or "regexes", are patterns for matching text. In this case, we’re matching the URLs people go to, and using regular expressions to match whole ‘groups’ of them at once.</div> (If you’d like to learn more about regular expressions, read the [http://diveintopython.net/regular_expressions/index.html Dive into Python guide to regular expressions] sometime. Or you can look at this [http://xkcd.com/208/ xkcd]. [http://regexpal.com/ Regexpal] is also a helpful tool for writing a regex.)
 
<div class="instructor">In addition to matching text, regular expressions can capture text. Capturing means to remember that part of the string, for later use. Regexes use parentheses () to wrap the parts they’re capturing.
 
For Django, when a regular expression matches the URL that a web surfer requests, Django extracts the captured values (if any) and passes them to a function of your choosing. This is the role of the callback function above. When a regular expression matches the url, Django calls the associated callback function with any captured parts as parameters. These callback functions typically live in one of your apps' views.py, so this will be much clearer after the next section.</div>
 
When we ran
Line 63:
* what function is then called?
* what arguments is that function called with?
 
Save urls.py. Start the dev server <source lang="bash">
# in django-for-designers/myproject
$ python manage.py runserver</source> and try that url out! What happens?
 
Save and commit your work.
 
<div class="instructor">The idea that a URL doesn’t have to map onto a file or a folder, or some other sort of static resource, is quite powerful. The URL is just a way of giving instructions to some server, somewhere. Note that in this example, both / and /bookmarks/ go to the same place -- they both activate bookmarks.views.index!
FIXME: Right now, this is an error. Should it not be an error?
 
(Rant: In Django, as in most modern frameworks, you have total control over the way your URLs look. People on the web won’t see cruft like .py or .php or even .html at the end of your URLs. There is no excuse for that kind of stuff in the modern era! (Though, putting .php on the end of all your Django URLs, while pointless, is kind of hilarious and super easy.))</div>
The idea that a URL doesn’t have to map onto a file or a folder, or some other sort of static resource, is quite powerful. The URL is just a way of giving instructions to some server, somewhere. Note that in this example, both / and /bookmarks/ go to the same place -- they both activate bookmarks.views.index!
 
(Rant: In Django, as in most modern frameworks, you have total control over the way your URLs look. People on the web won’t see cruft like .py or .php or even .html at the end of your URLs. There is no excuse for that kind of stuff in the modern era! (Though, putting .php on the end of all your Django URLs, while pointless, is kind of hilarious and super easy.))
 
=== Handling those URLs with some basic views ===
Line 92 ⟶ 86:
<source lang="python">url(r'^$', 'bookmarks.views.index', name='home')</source>
 
If we look in the bookmarks folder, we can see there's a views.py file... but if we look in that file, it's empty! So, our problem is that the URL parsing is going fine, but there is no one listening at the other end of the phone! This ViewDoesNotExist error happened because you haven’t written a function index() in the module bookmarks/views.py.
 
<div class="instructor">So, our problem is that the URL parsing is going fine, but there is no one listening at the other end of the phone! This ViewDoesNotExist error happened because you haven’t written a function index() in the module bookmarks/views.py.
 
Well, I guess we should do that!</div>
 
Let's write some views. Open bookmarks/views.py and put the following Python code in it:
Line 128 ⟶ 124:
=== Handling URLs with templates ===
 
These placeholder responses are okay, but you wouldn't want to make a real webpage in a giant Python string in the middle of a view function! Fortunately, Django comes with a built-in template renderer! Let's edit views.py. First, at the top, edit the imports to add one fresh import:
 
<source lang="python">
Line 240 ⟶ 236:
In Django's templating language, to put a variable into the template, put it inside double {&#8288;{ brackets }}. If you look at http://localhost:8000/tags/awesome/, you'll now see "awesome" (or whatever tag name you choose) in the space occupied by {&#8288;{ tag }}.
 
<div class="instructor">You'll notice--these two templates share an awful lot of code. Repeating yourself in this way is no fun, and a recipe for messy, inconsistent styling. Fortunately, Django templates support inheritance!</div>
 
Let's make a base.html template. This template isn't rendered by any view, but all (or most) of our templates can inherit from it:
Line 304 ⟶ 300:
The {% extends %} tag tells the template renderer which template this template file inherits from. Each block tag then specifies the content that ought to go in each block.
 
<div class="instructor">There are lots of built-in template tags and filters; we'll see a few more later. The full docs on them [https://docs.djangoproject.com/en/dev/ref/templates/builtins/ live here]. </div>
 
As a rule, in Django, things in {% %} control the "logic" of the template, while things in {&#8288;{ }} actually stick data into the template in particular places.
Line 310 ⟶ 306:
=== Static files ===
 
Now we know how to create HTML within Django's templating language. For a good web application, though, you will probably want to embed stylesheets, scripts, images, and other files. <div class="instructor">How can we include static files such as these?</div>
 
Move outside your myproject/ directory and move the contents of the sample-static-files/ folder that came with your git repo into myproject/bookmarks/.
Line 320 ⟶ 316:
$ git mv sample-static-files/* myproject/bookmarks/static/
</source>
 
TODO (Karen) Actually provide sample static files here, and play-test the rest of this section.
 
Django automatically looks for a folder named 'static' inside any of your Django apps. You can also put static files in other places, such as inside myproject/ directly. To do that, you would need to add the absolute path of the folder to STATICFILES_DIRS in settings.py.
 
<div class="instructor">For this tutorial we'll just leave our static files inside bookmarks/, for the sake of simplicity.</div>
 
For consistency, now is a good time to return to the directory we used to be in:
Anonymous user