Django官方文档里有一个投票Web应用的例子。建立好的目录如下:
mysite是project的名字,polls是这个应用。
.
├── db.sqlite3
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── settings.py
│ ├── settings.pyc
│ ├── urls.py
│ ├── urls.pyc
│ ├── wsgi.py
│ └── wsgi.pyc
└── polls
├── admin.py
├── admin.pyc
├── __init__.py
├── __init__.pyc
├── migrations
│ ├── 0001_initial.py
│ ├── 0001_initial.pyc
│ ├── __init__.py
│ └── __init__.pyc
├── models.py
├── models.pyc
├── tests.py
├── views.py
└── views.pyc
接下来梳理一下这个应用的数据库和实现。
##表结构
在Sqlite3中建立两个表,polls_poll
是投票信息表。
sqlite> select * from polls_poll;
id | question | pub_date
3|what is your name|2015-09-02 13:42:25
4|What kind of book do you like?|2015-09-05 08:59:00
polls_choice
是每个投票对应的选项表。
sqlite> select * from polls_choice;
id | choice_text | votes | poll_id
3|Xiao Ming|100|3
4|Xiao Hong|120|3
5|Xiao Hua|130|3
6|Xiao yi|200|3
7|Literature|111|4
8|History|234|4
9|Computer Science|98|4
polls_choice
中的poll_id
字段对应于polls_poll
的id
。这里是一个ForeignKey,主要作用是将两个表进行关联和约束。详情参加SQL FOREIGN KEY 约束。
models.py
from django.db import models
import datetime
from django.utils import timezone
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('data published')
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
model主要定义了Poll
和Choice
两个class,对应到DB中就是polls_poll
表和polls_choice
表,而question,pub_date这些变量名就是DB中的字段名,这就是ORM。详情参见为什么很多人都喜欢Django的ORM而不是SQLAlchemy?
admin.py
from django.contrib import admin
from .models import Poll, Choice
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date Information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
list_display = ('question', 'pub_date', 'was_published_recently')
list_filter = ['pub_date']
search_fields = ['question']
inlines = [ChoiceInline]
admin.site.register(Poll, PollAdmin)
这个文件用来控制web显示的样式和功能。
fieldsets
控制显示的内容
list_display
控制列表title。
list_filter
控制筛选条件,相当于直接生成了Mysql的WHERE...AND...AND
语句。
search_fields
控制搜索框,相当于直接生成了Mysql的WHERE...LIKE '%text%'
语句。
从这里可以看到Django是相当省时省力。
参考
https://docs.djangoproject.com/en/1.7/intro/tutorial02/
http://www.w3school.com.cn/sql/sql_foreignkey.asp
http://www.zhihu.com/question/19959765