Boston Python Workshop/Saturday/Web app project: Difference between revisions

Revert to pre-spam
imported>Paulproteus
imported>Paulproteus
(Revert to pre-spam)
 
(52 intermediate revisions by 12 users not shown)
Line 8:
 
This is based ''heavily'' on the official tutorial for the Django web programming framework.
 
This page should say what you should actually expect to know. It is okay that you don't understand everything you are typing in. After a lot more learning, you will be able to. The first time, though, it's okay if you don't. Will and Katie have feedback for this page.
 
== Writing your first Django app, part 1 ==
Line 38 ⟶ 40:
=== Look at the files ===
 
Let’s look at files are in the project:
 
workshop_mysite/
Line 59 ⟶ 61:
=== The development server ===
 
Let's verify this worked. If you haven't already, and runRun the command python manage.py runserver. You'll see the following output on the command line:
 
<pre>
python manage.py runserver
</pre>
 
You'll see the following output on the command line:
 
<pre>
Line 73 ⟶ 81:
 
Now that the server's running, visit http://127.0.0.1:8000/ with your Web browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel. It worked!
 
Exit the server by pressing CONTROL-C on your keyboard.
 
=== Fixing security settings ===
Line 165 ⟶ 175:
choice = models.CharField(max_length=200)
votes = models.IntegerField()
 
Save the models.py file.
 
All models in Django code are represented by a class that subclasses django.db.models.Model. Each model has a number of class variables, each of which represents a database field in the model.
Line 198 ⟶ 210:
'polls',
)
 
Save the settings.py file.
 
Now Django knows to include the polls app.
Line 267 ⟶ 281:
[<Poll: Poll object>]
 
Wait a minute. <Poll: Poll object> is, an utterly, an unhelpful representation of this object. Let's fix that by editing the polls model (in the polls/models.py file) and adding a __unicode__() method to both Poll and Choice:
Use your '''text editor''' to open the polls/models.py file and adding a __unicode__() method to both Poll and Choice:
 
class Poll(models.Model):
Line 293 ⟶ 308:
 
Note the addition of import datetime to reference Python's standard datetime module.
FIXME: add explanation of why we did this
 
Save these changes to the models.py file, and then start a new Python interactive shell by running python manage.py shell again:
 
>>> from polls.models import Poll, Choice
Line 305 ⟶ 321:
If you want to search your database, you can do it using the '''filter''' method on the ''objects'' attribute of Poll. For example:
 
>>> ppolls = Poll.objects.filter(question="What's up?")
>>> ppolls
[<Poll: What's up?>]
>>> ppolls[0].id
1
 
Line 327 ⟶ 343:
Right now, we have a Poll in the database, but it has no Choices. See:
 
>>> p = Poll.objects.get(pkid=1)
>>> p.choice_set.all()
[]
Line 338 ⟶ 354:
<Choice: The sky>
>>> c = p.choice_set.create(choice='Just hacking again', votes=0)
>>> c
<Choice: Just hacking again>
 
Line 363 ⟶ 380:
* Find SQLite Manager in '''Tools'''->'''SQLite Manager'''
* In the SQLite Manager menus, choose: '''Database'''->'''Connect Database'''
* Find the '''workshop_mysite/database.db''' file.
 
Browse your tables! This is another way of looking at the data you just created.
 
'''Note''': In order to find the ''database.db'' file, you might need to ask SQLite Manager to show you all files, not just the ''*.sqlite'' files.
I (the author of this tutorial) think it's really important that you be able to find this database file. So go ahead and do this step.
 
I (the author of this tutorial) think it's really important that you be able to find this database file. So go ahead and do this step. Browse around! Hooray.
 
When you're satisfied with your Poll data, you can close it.
 
=== Save and share our work ===
Line 450 ⟶ 472:
ROOT_URLCONF = 'workshop_mysite.urls'
 
That means that the default URLconf inis workshop_mysite/urls.py.
 
Time for an example. Edit mysitethe file workshop_mysite/urls.py so it looks like this:
 
<pre>
from django.conf.urls.defaults import *
 
Line 462 ⟶ 485:
(r'^polls/(\d+)/vote/$', 'polls.views.vote'),
)
</pre>
 
This is worth a review. When somebody requests a page from your Web site -- say, "/polls/23/", Django will load the ''urls.py'' Python module, because it's pointed to by the ROOT_URLCONF setting. It finds the variable named urlpatterns and traverses the regular expressions in order. When it finds a regular expression that matches -- r'^polls/(\d+)/$' -- it loads the function detail() from polls/views.py. Finally, it calls that detail() function like so:
 
Line 497 ⟶ 520:
return HttpResponse("Hello, world. You're at the poll index.")
 
This is the simplest view possible. GoSave the views.py file, then go to "/polls/" in your browser, and you should see your text.
 
Now letslet's add a few more views by adding to the views.py file. These views are slightly different, because they take an argument (which, remember, is passed in from whatever was captured by the regular expression in the URLconf):
 
def detail(request, poll_id):
Line 510 ⟶ 533:
return HttpResponse("You're voting on poll %s." % poll_id)
 
TakeSave the views.py file. Now take a look in your browser, at "/polls/34/". It'll run the detail() method and display whatever ID you provide in the URL. Try "/polls/34/results/" and "/polls/34/vote/" too -- these will display the placeholder results and voting pages.
 
=== Write views that actually do something ===
Line 520 ⟶ 543:
All Django wants is that HttpResponse. Or an exception.
 
Most of the Django views in the world use Django's own database API, which we covered in Tutorial 1. Let's do that, too. Here's one stab at the index() view, which displays the latest 5 poll questions in the system, separated by commas, according to publication date. Continue editing the file views.py:
 
from polls.models import Poll
Line 530 ⟶ 553:
return HttpResponse(output)
 
Now go to "http://localhost:8000/polls/" in your Web browser. You should see the text of the first poll. There's a problem here, though: The page's design is hard-coded in the view. If you want to change the way the page looks, you'll have to edit this Python code. So let's use Django's template system to separate the design from Python:
 
from django.shortcuts import render_to_response
Line 577 ⟶ 600:
</pre>
 
Load the page in"http://localhost:8000/polls/" into your Web browser again, and you should see a bulleted-list containing the "What's up" poll from Tutorial 1. The link points to the poll's detail page.
 
=== Raising 404 ===
 
Now, let's tackle the poll detail view -- the page that displays the question for a given poll. Continue editing the ''views.py'' file. This view uses Python ''exceptions'':
 
from django.http import Http404
Line 587 ⟶ 610:
def detail(request, poll_id):
try:
p = Poll.objects.get(pkid=poll_id)
except Poll.DoesNotExist:
raise Http404
Line 594 ⟶ 617:
The new concept here: The view raises the Http404 exception if a poll with the requested ID doesn't exist.
 
If you'd like to quickly get the above example working, just create a new template file and name it ''detail.html''. Enter in it just one line of code:
 
<pre>
Line 600 ⟶ 623:
</pre>
 
willto get you started for now.
 
Does your detail view work? Try it: http://127.0.0.1:8000/polls/1/
Add it to a new template file that you create, ''detail.html''.
 
DoesYou yourcan detailalso viewtry work?to Tryload ita poll page that does not exist, just to test out the pretty 404 error: http://127.0.0.1:8000/polls/detail/132/
 
=== Adding more detail ===
Line 624 ⟶ 647:
 
Method-calling happens in the {% for %} loop: poll.choice_set.all is interpreted as the Python code poll.choice_set.all(), which returns a sequence of Choice objects and is suitable for use in the {% for %} tag.
 
Load the new detail page in your browser: http://127.0.0.1:8000/polls/1/ The poll choices now appear.
 
=== Adding some style ===
Line 658 ⟶ 683:
* Since we're creating a POST form (which can have the effect of modifying data), we need to worry about Cross Site Request Forgeries. Thankfully, you don't have to worry too hard, because Django comes with a very easy-to-use system for protecting against it. In short, all POST forms that are targeted at internal URLs should use the {% csrf_token %} template tag.
 
The {% csrf_token %} tag requires information from the request object, which is not normally accessible from within the template context. To fix this, a small adjustment needs to be made to the detail view in the "views.py" file, so that it looks like the following:
 
<pre>
Line 669 ⟶ 694:
</pre>
 
The details of how this works are explained in the [http://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext documentation for RequestContext].
 
Now, let's create a Django view that handles the submitted data and does something with it. Remember, in Tutorial 3, we created a URLconf for the polls application that includes this line:
Line 776 ⟶ 801:
Okay, not quite finally. You might need to go to https://admin.alwaysdata.com/advanced/processes/ and click ''Restart my applications''.
 
Go to your alwaysdata site's /adminpolls/ page. For me, I'd go to:
 
* http://paulproteus.alwaysdata.com/adminpolls/
 
You should see your poll!
Create a poll! Create some choices. Find your views, and show them to the world.
 
== Part 4: Editing your polls in the Django admin interface ==
Line 944 ⟶ 969:
 
That's the basics of the Django admin interface!
 
Create a poll! Create some choices. Find your views, and show them to the world.
 
== Part 4.5: Deploy again, again! ==
Anonymous user