您好,登錄后才能下訂單哦!
?
目錄
django. 1
django-admin startproject. 3
django-admin startapp. 5
model:... 7
view中使用model:... 10
template. 11
view中使用template:... 13
去掉url和static硬編碼:... 15
url反解析:... 15
url命名空間:... 15
form處理:... 16
?
?
?
是py下一款著名的web框架;
?
框架,是整個或部分系統的可重用設計,表現為一組抽象構件及構件實例間交互的方法;
是可被應用開發者定制的應用骨架;
其它web框架:flask、tornado;
?
django優:
自帶輪子眾多,方便快速開發,如ORM、Auth、Cache、Template、From核心組件;
天生的MVC設計模式;
實用且強大的管理后臺;
簡潔的url設計;
周邊插件豐富;
?
django缺:
重;
同步阻塞;
?
django設計哲學:
大而全;
快速開發;
?
django歷史:
最初開發者,Adrian和Simon;
開發背景,World Online維護幾個新聞站點,要求快速發布新聞,快速建立其它新聞站點(快速開發、數據驅動);
World Online于05年夏天開源;
?
https://www.djangoproject.com/
?
(django) C:\django>pip install django==1.11
(django) C:\django>ipython
In [1]: import django
In [2]: django.get_version()
Out[2]: '1.11'
?
django version | python versions |
1.8 | 2.7,3.2,3.3,3.4,3.5 |
1.9,1.10 | 2.7,3.4,3.5 |
1.11 | 2.7,3.4,3.5,3.6 |
2.0 | 3.4,3.5,3.6 |
2.1 | 3.5,3.6,3.7 |
?
響應流程:
?
pycharm,New Project-->webproject,C:\webproject
(webproject) C:\webproject>django-admin startproject mysite?? #或用python manage.py startproject mysite;此命令腳本在虛擬環境的C:\Users\Administrator\py_env\webproject\Scriptsdjango-admin.exe
mysite/mysite/sessings.py?? #項目配置
?
mysite/mysite/urls.py?? #入口url
def url(regex, view, kwargs=None, name=None):?? #view是function object,不是函數調用;view函數的第一參數永遠是request,不探討CBV,view函數的返回值永遠是HttpResponse對象,顯式或隱式;
url(r'^hello/$', hello),?? #django默認會給url后加/,此處定義,hello前不帶/,hello后一定要有/,這樣即使用戶訪問http://127.0.0.1:8000/hello也會自動跳到http://127.0.0.1:8000/hello/上;若此處配置為r'^hello$',用戶訪問http://127.0.0.1:8000/hello/,訪問的地址無論是否帶/都會報404;所以記住,此處定義的url,hello前沒有/,hello后要有/;
url(r'^$', views.index, name='index')?? #app中的urls.py,可通過name反解出url;
url(r'^polls/', include('polls.urls')),?? #項目中的urls.py,include里是str,在用到時才動態導入;
?
mysite/mysite/wsgi.py?? #生產部署時調用
?
注:
include源碼,from django.conf.urls import url, include:
def include(arg, namespace=None, app_name=None):
?
?
例:
urls.py
from django.conf.urls import url
from django.contrib import admin
?
from django.http import HttpResponse
?
def index(request):
??? return HttpResponse('this is index')
?
def hello(request):?? #view函數的第一個參數永遠是request,不探討CBV
??? return HttpResponse('Hello world')
?
urlpatterns = [?? #urlpatterns約定俗成的名字
??? url(r'^$', index),
??? url(r'^hello/$', hello),?? #django默認會給url后加/,此處定義,hello前不帶/,hello后一定要有/,這樣即使用戶訪問http://127.0.0.1:8000/hello也會自動跳到http://127.0.0.1:8000/hello/上;若此處配置為r'^hello$',用戶訪問http://127.0.0.1:8000/hello/,訪問的地址無論是否帶/都會報404;所以記住,此處定義的url,hello前沒有/,hello后要有/
??? url(r'^admin/', admin.site.urls),
]
?
(webproject) C:\webproject\mysite>python manage.py runserver?? #可自定義ip:port,python manage.py runserver 0.0.0.0:8080,啟動的是django內置webserver,用于測試
?
?
?
?
django app與django project區別:
app中才能用model;
app設計是可插拔的,app不一定在project中;
settings.py中有內置的app,可根據項目情況禁用;
?
?
(webproject) C:\webproject\mysite>django-admin startapp polls?? #或用python manage.py startapp polls,新建投票app,在項目根下操作
admin.py?? #后臺管理
apps.py?? #1.8ver后加的,app的獨立配置
tests.py?? #測試用例
views.py?? #業務邏輯
migrations/?? #與model的版本控制有關
?
?
例:
mysite/mysite/settings.py?? #在項目settings.py中導入app
INSTALLED_APPS = [
??? 'polls.apps.PollsConfig',
??? 'django.contrib.admin',
??? 'django.contrib.auth',
??? 'django.contrib.contenttypes',
??? 'django.contrib.sessions',
??? 'django.contrib.messages',
??? 'django.contrib.staticfiles',
]
?
mysite/polls/views.py
from django.shortcuts import render
from django.http import HttpResponse
?
def index(request):
??? return HttpResponse('this is index at polls')
?
mysite/polls/urls.py?? #app中的urls.py默認不存在,新建
urlpatterns = [
??? url(r'^$', views.index, name='index')
]
?
mysite/mysite/urls.py
urlpatterns = [
??? url(r'^polls/', include('polls.urls')),?? #include中是str,在用到時才動態導入
??? url(r'^admin/', admin.site.urls),
]
?
?
?
支持sqlite、mysql、postgresql、oracle;
py3.5以上版本,不支持MySQLdb驅動;
可用pymysql,py寫的;
可用mysqlclient,c寫的,速度快,fork的MySQLdb,官方推薦;
?
ORM,用py的方法、數據結構,來訪問db,可兼容不同的DB;
?
一個class代表一張表,多對多會產生額外一張關系表;
默認pk為id,也可自定義pk;
表名默認為$APP_NAME$CLASS_NAME.lower(),表名小寫(跨平臺支持),可重寫;
?
models migrations:
定義好models.py需應用到db,django為了能跟蹤表結構的變化,增加了migration版本控制功能,如果沒有該功能,需手動編寫表結構變化的語句,重新導入數據;
?
models CRUD:
增:
q = Question(**kwargs)?? #方式1
q.save()
?
q = Question.objects.create(**kwargs)?? #方式2
?
刪:
q = Question.objects.get(id=1)
q.delete()
?
Question.objects.filter(id=1).delete()
Question.objects.all().delete()
?
改:
q = Question.objects.get(id=1)
q.question_text = 'some text'
q.save()
?
Question.objects.filter(id=1).update(question_text='why ?')
?
查:
Question.objects.all()
Question.objects.filter(question_text="what's up?")?? #objects,model默認的manager管理器
Question.objects.get(id=1)
latest_question_list = Question.objects.order_by('-pub_date')[:3]?? #默認升序,加上-倒序
?
注:
>>> from django.utils import timezone
>>> import datetime
>>> timezone.now()?? #比datetime.datetime.now()多了時區,在頁面展示時,django內部會轉為適合用戶所在的時區
datetime.datetime(2019, 1, 2, 7, 2, 18, 244920, tzinfo=<UTC>)
>>> datetime.datetime.now()
datetime.datetime(2019, 1, 2, 15, 2, 32, 837755)
?
models中方法:
def __str__(self):
???????? return self.question_text
def was_published_recently(self):
???????? return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
?
?
mysite/mysite/settings.py
DATABASES = {
??? 'default': {
??????? 'ENGINE': 'django.db.backends.sqlite3',
??????? 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
??? }
}
?
?
mysite/polls/models.py
from django.db import models
?
class Question(models.Model):?? #一個class代表一張表,多對多會產生額外一張關系表;默認pk為id,也可自定義pk;表名默認為$APP_NAME$CLASS_NAME.lower(),可重寫
??? question_text = models.CharField(max_length=200)
??? pub_date = models.DateTimeField('date published')
?
class Choice(models.Model):
??? question = models.ForeignKey(Question, on_delete=models.CASCADE)
??? choice_text = models.CharField(max_length=200)
??? votes = models.IntegerField(default=0)
?
(webproject) C:\webproject\mysite>python manage.py makemigrations?? #生成遷移記錄
(webproject) C:\webproject\mysite>python manage.py migrate?? #應用到db
(webproject) C:\webproject\mysite>sqlite3 db.sqlite3
sqlite> .tables
auth_group????????????????? django_admin_log
auth_group_permissions????? django_content_type
auth_permission??? ?????????django_migrations
auth_user?????????????????? django_session
auth_user_groups??????????? polls_choice
auth_user_user_permissions? polls_question
sqlite> .quit
?
(webproject) C:\webproject\mysite>dir polls\migrations\
?驅動器 C 中的卷是 OS
?卷的序列號是 000B-5D26
C:\webproject\mysite\polls\migrations 的目錄
2019/01/02? 14:24??? <DIR>????????? .
2019/01/02? 14:24??? <DIR>????????? ..
2019/01/02? 14:24???????????? 1,266 0001_initial.py
2019/01/02? 11:29???????????????? 0 __init__.py
2019/01/02? 14:25??? <DIR>????????? __pycache__
?????????????? 2 個文件????????? 1,266 字節
?????????????? 3 個目錄 77,168,365,568 可用字節
(webproject) C:\webproject\mysite>python manage.py sqlmigrate polls 0001_initial?? #查看sql語句是否是指定要求的
?
(webproject) C:\webproject\mysite>python manage.py shell? ?#進入交互式命令行
>>> from django.utils import timezone
>>> from polls.models import Question,Choice
>>> q = Question(question_text="what's new", pub_date=timezone.now())
>>> q.save()
>>> q.id
1
>>> q.pk
1
>>> q.question_text
"what's new"
>>> q.pub_date
datetime.datetime(2019, 1, 2, 6, 49, 16, 612213, tzinfo=<UTC>)
?
>>> from polls.models import Question,Choice
>>> from django.utils import timezone
>>> q = Question.objects.create(question_text="how are you?", pub_date=timezone.now())
>>> q = Question.objects.create(question_text="what's the weather?", pub_date=timezone.now())
>>> q = Question.objects.create(question_text="fuck you!", pub_date=timezone.now())
>>> q
<Question: fuck you!>
>>> q.was_published_recently()
True
>>> d = timezone.now() - timezone.timedelta(days=2)
>>> q.pub_date = d
>>> q.save()
>>> q.was_published_recently()
False
?
?
from django.http import HttpResponse
from .models import Question
?
def index(request):
??? latest_question_list = Question.objects.order_by('-pub_date')[:3]?? #默認升序,加上-倒序
??? output = ', '.join([q.question_text for q in latest_question_list])
??? return HttpResponse(output)
?
def detail(request, question_id):
??? return HttpResponse('Your are looking at question {}'.format(question_id))
?
def results(request, question_id):
??? response = 'Your are looking at results of question {}'.format(question_id)
??? return HttpResponse(response)
?
def vote(request, question_id):
??? return HttpResponse('Your are voting on question {}'.format(question_id))
?
?
django內置了自己的模板引擎,和jinja很像,使用簡單;
?
django默認會在app_name/templates/下尋找模板,在app_name/templates/下再建立app_name,這樣app_name/templates/app_name/下存放與該app相關的模板,因為默認django會去所有的app下找模板,可能會優先找到其它app下的模板;
默認會到app_name/static/下尋找靜態文件;
?
設置公用templates和公用static:
mysite/mysite/settings.py
TEMPLATES = [
??? {
??????? 'BACKEND': 'django.template.backends.django.DjangoTemplates',
??????? 'DIRS': [os.path.join(BASE_DIR, 'templates')],
??????? 'APP_DIRS': True,
……
STATIC_URL = '/static/'
STATICFILES_DIRS = [
??? os.path.join(BASE_DIR, 'static'),
]
?
?
>>> from django.template import Template,Context
>>> t = Template('My name is {{ name }}')
>>> c = Context({'name':'jowin'})?? #context可以是 dict、屬性、方法、tuple|list
>>> t.render(c)
'My name is jowin'
?
>>> t = Template('my name is {{ name }}')
>>> d = {'name':'jowin'}
>>> c = Context(d)
>>> t.render(c)
'my name is jowin'
?
>>> t = Template('my name is {{ user.name }}')?? #變量查找,dict、attr、method、list、tuple
>>> class Person:
...???? def __init__(self,name):
...???????????? self.name = name
...
>>> user = Person('jowin')
>>> user.name
'jowin'
>>> c = Context({'user':user})
>>> t.render(c)
'my name is jowin'
?
>>> t = Template('my name is {{ user.name }}')
>>> class Person:
...???? def name(self):
...???????????? return 'jowin'
...
>>> user = Person()
>>> user.name()
'jowin'
>>> c = Context({'user':user})
>>> t.render(c)
'my name is jowin'
?
模板引擎支持循環、判斷、過濾器:
for:
{% for person in person_list %}
<li> {{ person.name }} </li>
{% endfor %}
?
if:
{% if max > 10 %}
<li>max value is {{ max }} </li>
{% else %}
<li>max value is 10 </li>
{% endif %}
?
過濾器:
{{ now | date:"F j,Y" }}
{{ name | length }}
?
?
?
render源碼,from django.shortcuts import render:
def render(request, template_name, context=None, content_type=None, status=None, using=None):
??? """
??? Returns a HttpResponse whose content is filled with the result of calling
??? django.template.loader.render_to_string() with the passed arguments.
??? """
??? content = loader.render_to_string(template_name, context, request, using=using)
??? return HttpResponse(content, content_type, status)
?
另,render_to_response(),老版本1.6用;
?
?
mysite/polls/views.py
from django.http import HttpResponse
from .models import Question
from django.template import loader
?
# def index(request):
#???? latest_question_list = Question.objects.order_by('-pub_date')[:4]
#???? template = loader.get_template('polls/index.html')
#???? context = {'latest_question_list': latest_question_list}
#???? # output = ', '.join([q.question_text for q in latest_question_list])
#???? return HttpResponse(template.render(context))?? #方1
def index(request):
??? latest_question_list = Question.objects.order_by('-pub_date')[:4]
??? context = {'latest_question_list': latest_question_list}
??? return render(request, 'polls/index.html', context)?? #方2
?
mysite/polls/templates/polls/index.html
<img src="/static/django.png">?? #mysite/polls/static/django.png
{% if latest_question_list %}
??? <ul>
??????? {% for question in latest_question_list %}
??????? <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
??????? {% endfor %}
??? </ul>
{% endif %}
?
(webproject) C:\webproject\mysite>python manage.py runserver
?
?
?
mysite/polls/templates/polls/index.html
{% load static %}
?
<img src="{% static 'django.png' %}">
{% if latest_question_list %}
??? <ul>
??????? {% for question in latest_question_list %}
??????? <!--<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>-->
??????? <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
??????? {% endfor %}
??? </ul>
{% endif %}
?
注:
{% url 'detail' question.id %}?? #app的urls.py中定義的name有關;app namespace改后,'detail'改為'polls:detail';
?
?
?
正解析,url-->view;
反解析,view-->url;
?
>>> from django.shortcuts import reverse
>>> reverse('detail',kwargs={'question_id':1})
'/polls/1/'
?
另,reverse_lazy(),為解決循環依賴;
?
?
?
app namespace和instance namespace:
通常使用app namespace;
若app有多個include,使用instance namespace;
?
app namespace:
?
mysite/polls/urls.py?? #方1,建議使用,在app_name/urls.py中定義
app_name = 'polls'
?
mysite/mysite/urls.py
url(r'^polls/', include('polls.urls', app_name='polls')),?? #方2,在項目下定義mysite/mysite/urls.py
?
?
instance namespace:
instance級別,名稱不可以重復;
?
mysite/mysite/urls.py
url(r'^polls/', include('polls.urls', namespace='polls')),
?
?
?
mysite/polls/templates/polls/detail.html
<h2>{{ question.question_text }}</h2>
?
{% if error_message %}
??? <P><strong>{{ error_message }}</strong></P>
{% endif %}
?
<form action="{% url 'polls:vote' question.id %}">
{% 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>
?
?
mysite/polls/views.py
from django.shortcuts import render, get_object_or_404, reverse
from django.http import HttpResponse, HttpResponseRedirect
from .models import Question, Choice
from django.template import loader
# from django.core.urlresolvers import reverse
?
?
# def index(request):
#???? latest_question_list = Question.objects.order_by('-pub_date')[:4]
#???? template = loader.get_template('polls/index.html')
#???? context = {'latest_question_list': latest_question_list}
#???? # output = ', '.join([q.question_text for q in latest_question_list])
#???? return HttpResponse(template.render(context))
def index(request):
??? latest_question_list = Question.objects.order_by('-pub_date')[:4]
??? context = {'latest_question_list': latest_question_list}
??? return render(request, 'polls/index.html', context)
?
def detail(request, question_id):
??? # try:
??? #???? question = Question.objects.get(id=question_id)
??? # except Question.DoesNotExist:
??? #???? return HttpResponse('Not Found', status=404)
??? question = get_object_or_404(Question, pk=question_id)
??? return render(request, 'polls/detail.html', {'question': question})
?
def results(request, question_id):
??? question = get_object_or_404(Question, pk=question_id)
??? return render(request, 'polls/results.html', {'question': question})
?
def vote(request, question_id):
??? question = get_object_or_404(Question, pk=question_id)
??? print(request)
??? if request.method == 'POST':
??????? choice_id = request.POST.get('choice', 0)
??????? try:
??????????? selected_choice = question.choice_set.get(pk=choice_id)
??????? except Choice.DoesNotExist:
??????????? return render(request, 'polls/detail.html', {
?????????? ?????'question': question, 'error_message': 'You did not select a choice',
??????????? })
??????? else:
??????????? selected_choice.votes += 1
??????????? selected_choice.save()
??????????? return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
?
?
mysite/polls/templates/polls/results.html
<h2>{{ question.question_text }}</h2>
?
<ul>
??? {% for choice in question.choice_set.all %}
??? <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
??? {% endfor %}
</ul>
?
<a href="{% url 'polls:detail' question.id %}">Vote again?</a>
?
?
?
項目中使用:
pip install pymysql
pip install pillow?? #ImageField依賴
?
?
1、? 數據庫使用mysql:
項目目錄的__init__.py中
import pymysql
pymysql.install_as_MySQLdb()
?
DATABASES = {
? 'default': {
????? 'ENGINE': 'django.db.backends.mysql',
????? 'NAME': 'mxonline',
????? 'USER': 'mxonline',
????? 'PASSWORD': '123456',
????? 'HOST': '192.168.88.222',
????? 'PORT': 3306
? }
?
?
2、apps目錄下統一放app:
右鍵apps-->Mark directory as-->Source Root?? #解決編輯器查找,import時可在apps中找
?
import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))?? #解決命令行環境查找
?
?
?
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。