Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
NotificationsYou must be signed in to change notification settings

txrxlabs/intro-to-django

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Why django

  • python is developer friendly

  • large, open development community

  • internationalization

  • easy(ish) and powerful (sort of)

Hello python

$python>>>print'hello world'>>>defhello(name):print"hello "+name+"!">>>my_name='sweetie'>>>hello(my_name)

Hello django

The development runserver can be started in a terminal with the following command.

$ python manage.py runserver 0.0.0.0:8000

You can now view the django app onhttp://[websiteurl]:8000

As you can see, django gives us a very boring looking test page to let us know it is working.This page can be replaced by adding a url inintro/urls.py.

urlpatterns=patterns('',    (r'^$','intro.views.home'),# Snip!!)

Now it needs a functionhome in a fileviews.py. Createintro/views.py and enter in the following:

fromdjango.httpimportHttpResponsedefhome(request):returnHttpResponse("Hello Sweetie!")

This is fun, but tedious, so instead we use templates.

fromdjango.template.responseimportTemplateResponsedefhome(request):values= {'name':'Sweetie!'    }returnTemplateResponse(request,'base.html',values)

There is already a template inintro/templates/base.html. Add{{ name }} to it in the body

Simple Model (photos)

Start a new django app with$ python manage.py startapp photo. Add the following lines tophoto/models.py. Don't worry about a class is, for now just fake your way through it.

fromdjango.dbimportmodelscategory_choices= (  ('work','Work'),  ('play','Play'),)classPhoto(models.Model):src=models.ImageField(upload_to='photos/')name=models.CharField(max_length='100')uploaded=models.DateTimeField(auto_now_add=True)credit=models.CharField(max_length=50,null=True,blank=True)category=models.CharField(max_length=50,blank=True,choices=category_choices)

Now addphoto to theINSTALLED_APPS tuple inintro/settings.py. The photo app is now added to your project. However, it is not set up in the database. For that you need to run$ python manage.py syncdb. Full documentation on the built in types of fields can be found at:

https://docs.djangoproject.com/en/dev/ref/models/fields/#field-types

The Django Admin - Great power, little responsibility

Uncomment (remove the # from in front of) these lines inintro/urls.py:

fromdjango.contribimportadminadmin.autodiscover()# and down the page in the big list of urls    (r'^/admin/',include('admin.urls'),

Uncomment'django.contrib.admin' inINSTALLED_APPS halfway down the fileintro/settings.py. The admin is now visible on/admin/. The photo app does not appear because it is not registered. Register it by creatingphoto/admin.py with the following content.

fromdjango.contribimportadminfrommodelsimportPhotoadmin.site.register(Photo)

Now photos are accesible through the django admin. Try downloading a few images and adding them to the admin.

Connecting views.py and models.py

Open views.py and add the photos to thevalues dictionary

fromdjango.template.responseimportTemplateResponsefromphoto.modelsimportPhotodefhome(request):values= {'name':'Sweetie!','photos':Photo.objects.all(),    }returnTemplateResponse(request,'base.html',values)

And inside the body of base.html, print the photos with:

<ul>  {% for photo in photos %}<li><imgsrc="{{ MEDIA_URL }}{{ photo.url }}"alt="{{ photo.name }}"/><p>      {{ photo.name }}, by {{ photo.credit }}</p><p>      uploaded on {{ photo.uploaded }}</p></li>  {% empty %}<li>    There are no photos :(</li>  {% endfor %}</ul>

Bonus 3rd party app: sorl.thumbnail

  • Addsorl-thumbnail==11.12 torequirements.txt.

  • Run$ sudo pip install -r requirements.txt.

  • Addsorl.thumbnail toINSTALLED_APPS in the settings file.

  • run$ python manage.py syncdb

  • Changebase.html to use this new app:

{% load thumbnail %}<ul>  {% for photo in photos %}<li><ahref="{{ MEDIA_URL }}{{ photo.url }}">      {% thumbnail photo.src "200x200" crop="center" as im %}<imgsrc="{{ im.url }}"width="{{ im.width }}"height="{{ im.height }}"alt="{{ photo.name }}"/>      {% endthumbnail %}</a><p>      {{ photo.name }}, by {{ photo.credit }}</p><p>      uploaded on {{ photo.uploaded }}</p></li>  {% empty %}<li>    There are no photos :(</li>  {% endfor %}</ul>

Night 2

The Django Templating Language

Template variables are are passed in as the third argument to aTemplateResponse.This is a dictionary, usually called "values".Any variable can be printed by placing the{{ variable_name }} in braces in a template.Any functions are executed, anything else is converted to strings.Any attribute can be called with a dot like{{ variable_name.attribute }}.For models, this is set with the__unicode__ magic method.

classPhoto(models.Model):src=models.ImageField(upload_to='photos/')name=models.CharField(max_length='100')uploaded=models.DateTimeField(auto_now_add=True)credit=models.CharField(max_length=50,null=True,blank=True)category=models.CharField(max_length=50,blank=True,choices=category_choices)def__unicode__(self):return"A photo named "+self.name

Now in a template{{ photo }} has the same effect as writtingA photo named {{ photo.name }}.

Other than variables the only programming that can be done in templates are done through filters and tags.Template filters are applied with the pip like this:

pythontemplate inputtemplate outputnotes
x = "abcdef"{{ x }}abcdef
x = "abcdef"{{ x|length }}6
x = [1,2,3,4,5]{{ x|length }}5
x = "abcdef"{{ x|upper }}ABCDEF
x = 5{{ x|add:10 }}15
x = "arst"{{ x|upper|add:" is "|add:x }}ARST is arstTemplate filter argument can be a variable.
x = "arst"{{ x|add:5 }}Can't add int and string, fails silently

As you can see there is a lot you can do by "piping" variables together.Simple programming tools are available int tags.Tags are denoted with braces and percents{% tag %}.Some tags require an end tag.

pythontemplate inputtemplate outputnotes
x = range(4){{ x }}[0,1,2,3]A list of length 4
x = range(4){% for x in x %}
{{ x }}
{% endfor %}
0
1
2
3
x = []{% for x in x %}
{{ x }}
{% empty %}
There is nothing in x
{% endfor %}
There is nothing in x
x = [1,2,3]{% if x|length == 1 %}
There is one item in the list
{% elif not x %}
There are no items in the list
{% else %}
There are {{ x|length }} items in the list
{% endif %}
There are 3 items in this list.- `elif` is short for "else if"
- an empty list `[]` would be taken as `False`.
- `elif` and `else` are not required but `endif` is!
{% now "m/d/Y" %} 5/22/2012 - `now` requires a formatting string
- it does not take an `endnow` tag.
x = 'my name is chris'{% comment %}
Anything in here will not be printed.
{{ x }}
{% endcomment %}
- Useful for documentation and depracation.

Custom templates can be loaded with{% load thumbnail %} as seen above.Full documentation for built in template tags and template filters can be found at:

https://docs.djangoproject.com/en/dev/ref/templates/builtins/

Back to the models

Last time we made a photo model.This time we're going to improve on the (admittedly weak) category system.Then we'll add a comment system.First we need to put everything under a migration system to change the database without writting SQL.

  • South is already installed! Checkrequirements.txt if you don't believe me.

  • Add 'south' to the list ofINSTALLED_APPS insettings.py.

  • Add south to the database with$ python manage.py syncdb.($ implies you run in terminal)

  • Create an initial migration with$ python manage.py schemamigration photo --init.

  • Fake the migration with$ python manage.py migrate photo --fake

The photo app is now controlled by south migrations.Now we're ready to add a new model and modify the oldPhoto model.This uses a new fieldmodels.ForeignKey.

classCategory(models.Model):name=models.CharField(max_length='100')private=models.BooleanField(default=False)def__unicode__(self):returnself.nameclassPhoto(models.Model):src=models.ImageField(upload_to='photos/')name=models.CharField(max_length='100')uploaded=models.DateTimeField(auto_now_add=True)credit=models.CharField(max_length=50,null=True,blank=True)#category = models.CharField(max_length=50,blank=True,choices=category_choices)category=models.ForeignKey(Category)def__unicode__(self):return"A photo named "+self.name
  • create migration with$ python manage.py schemamigration --auto photo

  • run migration with$ python manage.py migrate photo

  • add the following code to the admin file to make category appear (try without looking first).

fromphoto.modelsimportCategory,Photoadmin.site.register(Category)

Now we can do the same with a comment model. At the end ofmodels.py add the following.Then add runschemamigration andmigrate usingmanage.py and we're ready to learn forms.

classComment(models.Model):photo=models.ForeignKey(Photo)screenname=models.CharField(max_length=20,null=True,blank=True)text=models.TextField()approved=models.BooleanField(default=False)added_on=models.DateTimeField(auto_now_add=True)

Clean Up the Templates

With multiple views we'll need a base template to save us a lot of writting.In the templates folder make a file calledhome.html.

{% extends "base.html" %}{% block content %}PUT EVERYTHING INSIDE THE &lt;BODY&gt; TAG INSIDE HERE{% endblock %}

And replace the body tag insidebase.html with the following:

<body><h1><ahref="/">    My Photo Gallery!!</a></h1>{% block content %}{% endblock %}</body>

Change theTemplateResponse template string to"home.html" like

returnTemplateResponse(request,'home.html',values)

If you don't have questions at this point, you aren't paying attention.

Display the comments on photo detail page

Now we need need to add a url, view, and template for adding comments to photos.At this pointurlpatterns inurls.py should look like.The url function allows us to give the url a name

urlpatterns=patterns('',    (r'^$','intro.views.home'),url(r'^photo/(\d+)/$','intro.views.photo_detail',name='photo_detail'))

Since there is no where that links to thephoto_detail view, we need to modifyhome.html.We use the template tag url like{% url url_name arg1 arg2 ... %}.The url name was set inurls.py as'photo_detail'.The only argument is thephoto.id (the bit in parenthesis in the url string).Django automatically looks up what url matches this and prints it as the tag output.

<ahref="{% url photo_detail photo.id %}">

And we need a view at'intro.views.photo_detail':

defphoto_detail(request,photo_id):photo=Photo.objects.get(id=photo_id)comments=photo.comment_set.all()comments=comments.filter(approved=True)values= {'photo':photo,'comments':comments,    }returnTemplateResponse(request,'photo_detail.html',values)

and a template (photo_detail.html in the templates directory):

{% extends "base.html" %}{% block content %}<imgsrc="{{ MEDIA_URL }}{{ photo.src }}"/><div>{{ photo.name }}</div><ul>  {% for comment in comments %}<li>    "{{ comment.text }}"<br/>    {{ comment.screenname }} at {{ comment.added_on }}</li>  {% empty %}<li>There are no comments.</li>  {% endfor %}</ul>{% endblock %}

Fun with Forms!

We're minutes away from having an (almost) useful app!!Normally you'd have to write a lot of html to show inputs, display errors, and show confirmation.But we can generate a generic form usingdjango.forms.ModelForm.Inviews.py:

fromdjangoimportformsfromphoto.modelsimportCommentclassCommentForm(forms.ModelForm):classMeta:model=Comment

Add'form': CommentForm(), to the values dictionary, and that's it!We now have all we need to print a form in the template.Inphoto_detail.html add the form as a table.

<formmethod="POST"><h2>Like what you see? Why not add a comment!</h2><table>  {{form.as_table}}</table><inputtype="submit"/></form>

Making the form actually do something

We need to add the data from the request object into the form.We also should remove the photo and approved fields because those are not set by the user.If the data is clean, save and redirect with a success message.

fromdjango.httpimportHttpResponseRedirectclassCommentForm(forms.ModelForm):classMeta:model=Commentexclude= ('photo','approved')defphoto_detail(request,photo_id):photo=Photo.objects.get(id=photo_id)comments=photo.comment_set.all()comments=comments.filter(approved=True)values= {'photo':photo,'comments':comments,'success':'success'inrequest.GET,    }form=CommentForm(request.POSTorNone)ifform.is_valid()andrequest.method=="POST":comment=form.save(commit=False)comment.photo=photocomment.save()returnHttpResponseRedirect(request.path+"?success=true")values['form']=formreturnTemplateResponse(request,'photo_detail.html',values)

We add a conditional,{% if request.GET.success %}, to display a success message.Also we need to to hide thephoto. Inphoto_detail.html:

{% if request.GET.success %}<p>  Thank you for your comment! It has been submitted for approval.</p>{% else %}<formmethod="POST">  {% csrf_token %}<h2>Like what you see? Why not add a comment!</h2><table>  {{form.as_table}}</table><inputtype="submit"/></form>{% endif %}

That should do it for the day.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp