1 create project
django-admin startproject *project-name*
基本设置 settings.py
Database:
default->sqlite3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
#’django.db.backends.postgresql_psycopg2’,’django.db.backends.mysql’, or ’django.db.backends.oracle’
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#filename and path of .db
}
}
other database should set ‘USER’,’PASSWORD’,’HOST’
TimeZone:
TIME_ZONE = 'UTC'
INSTALLED_APPS:
需要运行的APP
- django.contrib.admin – The admin site. You’ll use it in part 2 of this tutorial.
- django.contrib.auth – An authentication system.
- django.contrib.contenttypes – A framework for content types.
- django.contrib.sessions – A session framework.
- django.contrib.messages – A messaging framework.
- django.contrib.staticfiles – A framework for managing static files.
note: 要使用这些app必须要创建数据库表
python manage.py migrate
指令检查 这些应用的settings,并建立表。
开发用服务器
python manage.py runserver
使用其他端口
python manage.py runserver 0.0.0.0:8080
2 Create Models(数据模型)
project vs app: 一个项目可以有很多app
创建app
python manage.py startapp polls
在这个app中我们创建俩种数据。放在polls/models.py
中。
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(‘date published’)
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
更新数据models
在mysite/settings.py的 INSTALLED_APPS中加入polls
INSTALLED_APPS
= ( ‘django.contrib.admin’, ‘django.contrib.auth’, ‘django.contrib.contenttypes’,
‘django.contrib.sessions’, ‘django.contrib.messages’, ‘django.contrib.staticfiles’, ‘polls’, )
创建migration(这是一个中间记录迁移记录,并不会更新数据库,只是记录当前的数据库更新,而且还是泛型的)
python manage.py makemigrations polls
显示migration的具体的sql语句(针对某一个sql)
python manage.py sqlmigrate polls 0001
真正的更新数据库:
python manage.py migrate
3 Django Shell
进入项目的shell
python manage.py shell
创建数据项、数据项操作
>>> from polls.models import Question, Choice # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
[]
# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> q.save()
># Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> q.id
1
# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() displays all the questions in the database.
>>> Question.objects.all()
[<Question: Question object>]
4 创建admin用户
1.python manage.py createsuperuser
2.启动开发服务器python manage.py runserver
3.进入/admin/域名,会显示数据库的表
4.将Question变得可编辑。在polls/admin.py
中注册Question
from .models import Question
admin.site.register(Question)
5.进入修改数据项
自定义admin表
元素显示
1.重排Question中子元素顺序:fields
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = [’pub_date’, ‘question_text’]
admin.site.register(Question, QuestionAdmin)
2.将子元素划分不同组:fieldsets
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [ (None, {‘fields’: [’question_text’]}), (‘Dateinformation’,{‘fields’: [’pub_date’]}), ]
admin.site.register(Question, QuestionAdmin)
3.为子元素指定HTML的class, 使用fields中设定’classes’属性
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [ (None, {‘fields’: [’question_text’]}), (‘Dateinformation’,{‘fields’: [’pub_date’], ‘classes’: [’collapse’]}),]
admin.site.register(Question, QuestionAdmin)
4.指定多外键inlines
,stackedInline
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [ (None, {‘fields’: [’question_text’]}), (‘Dateinformation’,{‘fields’: [’pub_date’], ‘classes’: [’collapse’]}),]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
5.TarbularInline
压缩式多外键,替换stackedInline
列表显示
1.列表显示的样式。admin.ModelAdmin
的属性list_display
,列表显示元素的属性,而不是只显示名字
list_display = (‘question_text’,‘pub_date’,‘was_published_recently’)
2.列表显示的功能。list_filter
,search_fields
增加筛选和搜索功能
list_filter = ['pub_date']
search_fields = ['question_text']
3.其他功能:
Change list pagination, search boxes, filters, date-hierarchies, and column-header-ordering all work together like you think they should.
自定义admin样式
1.polls下新建Templates文件夹。用以存放模板。
2.mysite/settings.py增加一个DIRS在TEMPLATES设置中。
TEMPLATES = [
{
‘BACKEND’:‘django.template.backends.django.DjangoTemplates’,
‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)],
‘APP_DIRS’: True,
‘OPTIONS’: {
‘context_processors’: [
‘django.template.context_processors.debug’,
django.template.context_processors.request’,
‘django.contrib.auth.context_processors.auth’,
‘django.contrib.messages.context_processors.messages’,
],
},
},
]
3.在Templates文件夹下新建admin文件夹,将django的admin/base_site.html拷贝到此处。
4.自定义更改
5 VIEWS
url和视图函数
django将URL与VIEWS对应。使用一个URLconfs
转换。
1.polls/views.py
写界面函数
from django.http import HttpResponse
def index(request):
return HttpResponse(“Hello, world. You’re at the polls index.”)
2.polls/urls.py
定向app的urls
from . import views
from django.conf.urls import include, url
urlpatterns = [ url(r’^$’, views.index, name=’index’), ]
3.mysite/urls.py
包含到总urls
urlpatterns = [ url(r’^polls/’, include(‘polls.urls’)), url(r’^admin/’, include(admin.site.urls)), ]
4.url()函数参数
- regex字符:匹配字符
- view函数名
- kwargs:可以传递表,给视图函数
- name:模糊名,全局使用。可以在模板中使用
带参数的url
from django.conf.urls import url
from . import views
urlpatterns = [
# ex: /polls/
url(r’^$’, views.index, name=’index’),
# ex: /polls/5/
url(r’^(?P<question_id>[0-9]+)/$’,views.detail, name=’detail’),
#ex: /polls/5/results/
url(r’^(?P<question_id>[0-9]+)/results/$’,views.results,name=’results’),
# ex: /polls/5/vote/
url(r’^(?P<question_id>[0-9]+)/vote/$’, views.vote, name=’vote’),
]
def results(request, question_id):
pass
def detail(request, question_id):
pass
“/polls/34/” 的Django调用方式
detail(request=, question_id=’34’)
高级的VIEW编写
1.读取数据库输出
from django.http import HttpResponse
from .models import Question
def index(request):
latest_question_list =Question.objects.order_by(‘-pub_date’)[:5]
output = ‘,‘.join([p.question_text for p in latest_question_list])
return HttpResponse(output)
2.使用模板 Templates
- 创建目录 polls/templates/polls/index.html
- 用template_loader以 polls/index.html
访问
- 编写django定义的模板
模板有点类似于php了
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %} <li>
<a href=”/polls/{{ question.id }}/”>{{ question.question_text}}</a>
</li>
{% endfor %}
</ul>
{% else %} <p>No polls are available.</p>
{% endif %}
- 重写view
from django.http import HttpResponse
from django.template import RequestContext, loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by(‘-pub_date’)[:5] tem
plate = loader.get_template(‘polls/index.html’)
context = RequestContext(request, { ‘latest_question_list’: latest_question_list, })
return HttpResponse(template.render(context))
3.更简单的方式render()
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by(‘-pub_date’)[:5]
context ={‘latest_question_list’: latest_question_list}
return render(request, ‘polls/index.html’, context)
4.返回404
from django.http import Http404
from django.shortcuts import render
from .models import Question # ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404(“Question does not exist”)
return render(request,‘polls/detail.html’, {‘question’: question})
5.get_object_or_404()
,get_list_or_404()
404的捷径
from django.shortcuts import get_object_or_404,render
from .models import Question
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, ‘polls/detail.html’, {‘question’: question})
模板系统
点查找
如下面的代码
<h1>{{ question.question_text }}</h1>
<ul> {% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %} </ul>
- 属性查找
question.question_text
- 首先字典查找
- 属性查找
- list-index查找
- 方法调用
question.choice_set.all
实际上执行question.choice_set.all()
。
模板类型
- {{}}变量模板
{%url 'detail' question.question_id %}
超链接模板,调用全局视图函数。{% if var %} {% else %} {% endif %}
{% for var in list %} {% endfor %}
URL的名称域
在include函数中之中设置名称域
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [ url(r’^polls/’, include(‘polls.urls’,namespace=”polls”)), url(r’^admin/’,include(admin.site.urls)), ]
在模板中调用之中用’:’调用
<li><a href=”{% url ‘polls:detail’ question.id %}”>{{question.question_text
}}</a></li>
表单
前端form
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action=”{% url ‘polls:vote’ question.id %}” method=”post”>
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type=”radio” name=”choice” id=”choice{{ forloop.counter }}” value=”{{ choice.id }}”/>
<label for=”choice{{ forloop.counter }}”>{{choice.choice_text }}</label>
<br />
{% endfor %}
<input type=”submit” value=”Vote” />
</form>
后台python
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from .models import Choice, Question # ...
def vote(request, question_id):
p = get_object_or_404(Question, pk=question_id)
try: selected_choice = p.choice_set.get(pk=request.POST[’choice’])
except (KeyError,Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, ‘polls/detail.html’, { ‘question’:
p, ‘error_message’: “You didn’t select a choice.”, })
else:
selected_choice.votes += 1
selected_choice.save()
#Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse(‘polls:results’, args=(p.id,)))
request.POST
是一个字典。通过key获得提交值。request.POST
如果键值不存在会抛出异常。以上代码捕获异常。- 每次POST成功都要redirect,使用
HttpResponseRedirect()
函数 reverse()
逆向调用全局视图函数
使用通用视图
1.修改URLconfs
from django.conf.urls import url
from . import views
urlpatterns = [
url(r’^$’, views.IndexView.as_view(), name=’index’),
url(r’^(?P<pk>[0-9]+)/$’,views.DetailView.as_view(), name=’detail’), url(r’^(?P<pk>[0-9]+)/results/$’,views.ResultsView.as_view(),name=’results’),
url(r’^(?P<question_id>[0-9]+)/vote/$’, views.vote, name=’vote’),
]
2.修改视图函数