Getting Started With
Kevin Grinberg & John Obelenus
@activefrequency
May 24, 2011
Kevin Grinberg & John Obelenus
@activefrequency
May 24, 2011
Django docs = killer feature
http://docs.djangoproject.com(Examples shamelessly stolen from official tutorial*)
* which this is not.
Built-in development* web server
$ python manage.py runserver
* not for production!
"...collection of configuration and apps for a particular Web site"
Distinct unit of functionality
$ python django-admin.py startproject mysite
$ cd mysite
$ python manage.py startapp myapp
Just Python modules!
mysite/
__init__.py
manage.py
settings.py
urls.py
myapp/
__init__.py
models.py
tests.py
views.py
?
models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField('Post Body')
pub_date = models.DateTimeField('Date Published',
auto_now_add=True)
def __unicode__(self):
return self.title
Creating the Database
$ python manage.py syncdb
In the shell
$ python manage.py shell
>>> from myapp.models import Post >>> from datetime import datetime >>> p = Post(title='New Post') >>> p.body = 'Lorem Ipsum' >>> p.save() >>> p2 = Post.objects.get(id=1) >>> p3 = Post.objects.get(title='New Post') >>> posts = Post.objects.filter(pub_date__gte=datetime(2011, 1, 1) >>> posts = posts.filter(title__contains='Django') >>> print posts
urls.py
from django.conf.urls.defaults import *
from myapp import views
urlpatterns = patterns('',
(r'^about/$', views.about),
(r'^blog/post/(\d+)/$', views.view_post, name="post"),
(r'^blog/by-month/(?P<year>\d{4})/(?P<month>\d{2})/$',
views.posts_by_month, name='posts_by_month'),
(r'^blog/post/(\d+)/post-comment/$', views.post_comment),
)
views.py
from django.http import HttpResponse
def about(request):
return HttpResponse("Hello World")
def view_post(request, post_id):
return HttpResponse("Post %d" % post_id)
def posts_by_month(request, month, year):
return HttpResponse("Posts for %d/%d" % (year, month,))
views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import Http404
from myapp.models import Post
def view_post(request, post_id):
try:
p = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
raise Http404
return render_to_response('myapp/post.html',
{'post': p },
context_instance=RequestContext(request))
post.html
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<h3>{{ post.pub_date }}</h3>
<p>{{ post.body }}</p>
</body>
</html>
post.html
<h1>{{ post.title|upper }}</h1>
<h3>{{ post.pub_date|date:"m/d/Y" }}</h3>
post.html
{% if post.id == 1 %}
This is the first post!
{% endif %}
base.html
<html>
<head><title>{% block title %}My Site{% endblock %}</title></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
page.html
{% extends "base.html" %}
{% block title %}{{ block.super }} | Page Title{% endblock %}
{% block content %}
<p>Some content.</p>
{% endblock %}
forms.py
from django import forms
class ArchiveForm(forms.Form):
year = forms.ChoiceField(choices=range(2009, 2013), empty_label=None)
month = forms.ChoiceField(choices=range(1,13), empty_label=None)
sidebar_archive.html
<form action="{{ url }}" method="POST">
<ul>
{{ form.as_ul }} {# form.as_table #} {# form.as_p #}
</ul>
<input type="submit">
</form>
views.py
from myapp.forms import ArchiveForm
from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponseRedirect
def redirect_to_archive(request):
if request.method == "POST":
archive_form = ArchiveForm(data=request.POST)
if archive_form.is_valid():
year = archive_form.cleaned_data.get('year')
month = archive_form.cleaned_data.get('month')
return HttpResponseRedirect(reverse('posts_by_month',
args={'year': year, 'month': month}))
else:
raise Http404
else:
return HttpResponseRedirect("/")
models.py
class Comment(models.Model):
created_on = models.DateField(auto_now_add=True)
name = models.CharField(max_length=50)
email = models.EmailField()
body = models.TextField()
post = models.ForeignKey('Post')
forms.py
from django import forms
from myapp.models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('name', 'email', 'body')
views.py
from django.http import HttpResponseBadRequest, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404
from myapp.forms import CommentForm
from myapp.models import Comment, Post
def post_comment(request, post_id):
post = get_object_or_404(Post, id=post_id)
if request.method == 'POST':
comment = Comment(post=post)
comment_form = CommentForm(instance=comment,
data=request.POST)
if comment_form.is_valid():
comment_form.save()
return HttpResponseRedirect(reverse('post',
args=[post_id])
else:
return HttpResponseBadRequest()
from django import forms
from myapp.models import Comment
from datetime import datetime, timedelta
class CommentForm(forms.ModelForm):
body = forms.CharField(widget=forms.Textarea(
attrs={'rows': 5, 'cols': 40}))
def clean(self):
email = self.cleaned_data.get(email)
one_minute_ago = datetime.now() - timedelta(minutes=1)
recent_comments = Comment.objects.filter(email=email,
created_on__gte=one_minute_ago)
if recent_comments.count() > 0:
raise forms.ValidationError('You talk too much!')
return self.cleaned_data
class Meta:
model = Comment
fields = ('name', 'email', 'body')
admin.py
from myapp.models import Post, Comment
from django.contrib import admin
admin.site.register(Post)
class CommentAdmin(admin.ModelAdmin):
list_display = ('email', 'created_on')
list_filter = ('post', )
search_fields = ('name', 'email')
admin.site.register(Comment, CommentAdmin)
Override-able ModelForm
Filter, Search, etc.
django-debug-toolbar
django-extensions
$ python manage.py shell_plus From 'auth' autoload: Permission, Group, User, Message From 'contenttypes' autoload: ContentType From 'sessions' autoload: Session From 'sites' autoload: Site From 'myapp' autoload: Post, Comment From 'admin' autoload: LogEntry >>>
Also: create_superuser, print_user_for_session, etc.
It's Python!
import os MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
from django.conf import settings
def analytics(request):
return {'ANALYTICS_CODE': settings.ANALYTICS_CODE,
'ANALYTICS_DOMAIN': settings.ANALYTICS_DOMAIN,
}