Anonymous user
Django for ISchoolers: Difference between revisions
→Chunk 3
imported>Aldeka |
imported>Aldeka |
||
Line 692:
</source>
== Database migrations and South, part two ==
=== Changing your models ===
Oh no! Our client, LulzTech, has decided to change the spec for this prototype.
* Open qandabear/models.py and edit the
<source lang="python">
Line 717 ⟶ 710:
The default parameter lets us set a default value for this field if an answer's vote count isn't explicitly specified. Most new answers are going to have zero votes, so we set our default to 0.
* Make a migration so
<source lang="python">
Line 723 ⟶ 716:
</source>
* Apply the migration.
<source lang="python">
$ python manage.py migrate qandabear
Running migrations for qandabear:
- Migrating forwards to 0002_auto__add_field_answer_votes.
> qandabear:0002_auto__add_field_answer_votes
- Loading initial data for qandabear.
No fixtures found.
</source>
Success!
===Save and commit===
You know the drill!
<!--
== Let's auto-populate some data (using a script in the shell)! == -->
== Views with actual data ==
In Django, each view is responsible for doing one of two things: returning an HttpResponse object containing the content for the requested page, or raise-ing an exception such as Http404.
Your view can read records from a database, or not. It can use a template system such as Django’s – or not. It can generate a PDF file, output XML, create a ZIP file on the fly, anything you want, using whatever Python libraries you want. All Django wants is that at the end, it gets an HttpResponse or an exception out of your view function.
Most of the Django views in the world use Django’s own database API, which was touched on in the discuss of models, to write or show dynamic data to the user in some fashion. Right now, our views are very simple, and don't use the data in our database at all. Let's fix that.
=== Write a better index() view ===
To match the spec, our index page should displays the latest 5 questions in the system, separated by commas, according to publication date.
* Edit views.py:
<source lang="python">
from qandabear.models import Question
from django.http import HttpResponse
def index(request):
latest_qs = Question.objects.all().order_by('-pub_date')[:5]
output = ', '.join([q.text for q in latest_qs])
return HttpResponse(output)
</source>
Restart the dev server, and navigate to [http://127.0.0.1:8000/questions/ http://127.0.0.1:8000/questions/]. You should see the text of the last 5 polls (or fewer than five, if you haven't made that many yet).
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 view code. That's silly.
* Use Django’s template system to separate the design from Python:
<source lang="python">
from django.shortcuts import render_to_response
from qandabear.models import Question
def index(request):
latest_qs = Question.objects.all().order_by('-pub_date')[:5]
context = {'latest_qs': latest_qs}
return render_to_response('qandabear/index.html', context)
</source>
To recap what this does:
* Creates a variable called latest_poll_list. Django queries the database for all Poll objects, ordered by pub_date with most recent first, and uses slicing to get the first five.
* Creates a variable called context that is a dictionary with one key.
* Evaluates the render_to_response function with two arguments, and returns whatever that returns.
render_to_response loads the template called polls/index.html and passes it a value as context. The context is a dictionary mapping template variable names to Python objects.
If you can read this this view function without being overwhelmed, then you understand the basics of Django views. Now is a good time to reflect and make sure you do:
# What would you have to change to get 10 polls?
# What if you wanted the first 10 by name instead of by publication date?
* Reload [http://127.0.0.1:8000/questions/ http://127.0.0.1:8000/polls/]. Now you’ll see an error:
<source lang="python">
TemplateDoesNotExist at /questions/
polls/index.html
</source>
Ah. There’s no template yet. Let’s make one!
* Make a qandabear/templates/qandabear directory where templates will live. Right alongside the views.py for the qandabear app. This is what I would do:
<source lang="python">
mkdir -p qandabear/templates/qandabear
Edit qandabear/templates/qandabear/index.html to contain.
{% if latest_qs %}
<ul>
{% for question in latest_qs %}
<li><a href="/questions/{{ question.id }}/">{{ question.text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No questions are available.</p>
{% endif %}
</source>
* Edit TEMPLATE_DIRS in settings.py to have the full path to the templates folder inside your new app. On my computer, this looks like:
<source lang="python">
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'/karen/Code/django-for-ischoolers/mysite/qandabear/templates',
)
</source>
* Reload [http://127.0.0.1:8000/questions/ http://127.0.0.1:8000/questions/] . You should see a bulleted-list containing up to five of your questions. There should also be link pointing to the question's detail page.
*Save and commit.
= Chunk 4 =
|