一.安装与项目的创建

1.安装

  pip install django

2.查看版本

  python -m django --version

3.创建项目

  django-admin startproject mysite

    manage.py 实用的与django项目进行交互的命令行工具
    mysite 项目中的实际python包
    mysite/__init__.py 空文件,表示这是一个python包
    mysite/settings.py 此项目的配置文件
    mysite/urls.py url声明文件
    mysite/wsgi.py wsgi服务器的配置文件

4.启动开发模式下的服务器

  python manage.py runserver 0.0.0.0:8000

    浏览器访问:http://127.0.0.1:8000/

5.创建应用

  在manage.py的同级目录下执行:

    python manage.py startapp molin

6.第一个视图文件

polls/views.py

#_*_coding:utf8_*_
from django.shortcuts import HttpResponse
def index(request):
return HttpResponse("你好,欢迎来到投票系统的主页")

7.配置URL

  新增polls/urls.py文件

#_*_coding:utf8_*_
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]

8.将polls/urls.py引入到mysite/urls.py文件中, 因为所有的url配置入口都是源于mysite/urls.py

  mysite/urls.py

from django.contrib import admin
from django.urls import path, include urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
当浏览器访问 http://127.0.0.1:8000/polls/ 时,匹配到url规则path('polls/', include('polls.urls')), 然后读到polls/urls.py的配置:path('', views.index, name='index'), 从而去执行polls/views.py的index方法

二.模型与数据库的交互

1.数据库的设置

  打开mysite/settings.py,可看到默认情况下,django使用的是sqlite3数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

有些应用要求我们必须至少要有一个数据库,如,django的后台,因此,让我们先来执行以下命令: $ python manage.py migrate

  将django激活的应用所需的数据表创建好

2.创建模型

  polls/models.py

#_*_coding:utf8_*_

from django.db import models

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, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)

类中的每个属性映射为一个字段,并标识了这些字段的类型

3.激活模型

  mysite/settings.py

INSTALLED_APPS = [
'polls.apps.PollsConfig',
# ...
]

4.生成迁移

  $ python manage.py makemigrations polls

  自动生成了polls/migrations/0001_initial.py文件,现在还没有真正创建数据表,需要再执行数据迁移才能生成数据表

  执行迁移:$ python manage.py migrate

5.让django的命令行交互更友好

  polls/models.py

from django.db import models

class Question(models.Model):
# ...
def __str__(self):
return self.question_text class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text

__str__()函数将会返回我们定义好的数据格式。此外,我们还可以在models中添加自定义方法:

import datetime

from django.db import models
from django.utils import timezone class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

6.进入交互模式对数据库进行操作

  $ python manage.py shell

In [1]: from polls.models import Question, Choice

In [2]: Question.objects.all() # 获取所有问题
Out[2]: <QuerySet [<Question: 问题2>]> In [3]: Question.objects.filter(id=1) # 获取id为1的数据
Out[3]: <QuerySet [<Question: 问题2>]> In [8]: Question.objects.filter(question_text__startswith='问题') # 获取内容包含'问题'的数据
Out[8]: <QuerySet [<Question: 问题2>]> In [9]: from django.utils import timezone In [10]: current_year = timezone.now().year In [11]: Question.objects.get(pub_date__year=current_year)
Out[11]: <Question: 问题2> In [12]: Question.objects.get(id=2) # 当获取的数据不存在时,会报以下错误
---------------------------------------------------------------------------
DoesNotExist Traceback (most recent call last)
<ipython-input-12-75091ca84516> in <module>()
----> 1 Question.objects.get(id=2) In [13]: Question.objects.get(pk=1)
Out[13]: <Question: 问题2> In [14]: q = Question.objects.get(pk=1) In [15]: q.was_published_recently() # 调用自定义的方法
Out[15]: True In [16]: q = Question.objects.get(pk=1) In [17]: q.choice_set.all()
Out[17]: <QuerySet []>
In [19]: q.choice_set.create(choice_text='选项1', votes=0)
Out[19]: <Choice: 选项1> In [20]: q.choice_set.create(choice_text='选项2', votes=0)
Out[20]: <Choice: 选项2> In [21]: c = q.choice_set.create(choice_text='选项3', votes=0) In [22]: c.question
Out[22]: <Question: 问题2> In [23]: q.choice_set.all()
Out[23]: <QuerySet [<Choice: 选项1>, <Choice: 选项2>, <Choice: 选项3>]> In [24]: q.choice_set.count()
Out[24]: 3
In [25]: Choice.objects.filter(question__pub_date__year=current_year)
Out[25]: <QuerySet [<Choice: 选项1>, <Choice: 选项2>, <Choice: 选项3>]> In [26]: c = q.choice_set.filter(choice_text__startswith='选项3') In [27]: c.delete()
Out[27]: <bound method QuerySet.delete of <QuerySet [<Choice: 选项3>]>> In [29]: Choice.objects.filter(question__pub_date__year=current_year)
Out[29]: <QuerySet [<Choice: 选项1>, <Choice: 选项2>]>

7.创建后台管理员   

django自带了一个管理后台,我们只需创建一个管理员用户即可使用
创建一个后台管理员用户: $ python manage.py createsuperuser

8.引入模型

  polls/admin.py

#_*_coding:utf8_*_
from django.contrib import admin
from .models import Question
admin.site.register(Question)

登陆后台可以对模型进行操作

三.视图views和模板template的操作

1.django的视图用于处理url请求,并将响应的数据传递到模板,最终浏览器将模板数据进行渲染显示,用户就得到了想要的结果

  增加视图:polls/views.py

#_*_coding:utf8_*_
from django.shortcuts import HttpResponse
def index(request):
return HttpResponse("你好,欢迎来到投票系统的主页") def detail(request, question_id):
return HttpResponse('你正在查看问题%s' % question_id) def results(request, question_id):
response = '你正在查看问题%s的结果'
return HttpResponse(response % question_id) def vote(request, question_id):
return HttpResponse('你正在给问题%s投票' % question_id)

  配置url:polls/urls.py

#_*_coding:utf8_*_
from django.urls import path
from . import views
urlpatterns = [
# /polls/
path('', views.index, name='index'),
# /polls/1/
path('<int:question_id>/', views.detail, name='detail'),
# /polls/1/results/
path('<int:question_id>/results/', views.results, name='results'),
# /polls/1/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]

2.通过视图直接返回的数据,显示格式很单一,要想显示丰富的数据形式,就需要引用模板,用独立的模板文件来呈现内容。

  新增模板:polls/templates/polls/index.html

{% 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>问题为空</p>
{% endif %}

  修改视图: polls/views.py 传递变量给模板

#_*_coding:utf8_*_
from django.shortcuts import HttpResponse
from django.template import loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = {'latest_question_list': latest_question_list}
return HttpResponse(template.render(context, request))

开发中,直接使用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)

详情页的展示:polls/views.py

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('问题不存在')
return render(request, 'polls/detail.html', {'question': question})

404页面抛出的便捷写法:get_object_or_404()

polls/views.py

from django.shortcuts import render, get_object_or_404
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>

3.优化

  去掉url的硬编码格式

<li><a href="{% url 'detail' question.id %}">{{question.question_text}}</a></li>

  修改url配置 

  将polls/urls.py的详情页url由:path('<int:question_id>/', views.detail, name='detail')改为:
    path('specifics/<int:question_id>/', views.detail, name='detail')

    此时,index.html的url会自动由 http://127.0.0.1:8000/polls/1/ 转为 http://127.0.0.1:8000/polls/specifics/1/

4.一个项目中多个应用的区分需要使用命名空间

#_*_coding:utf8_*_
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]

将index.html的url生成代码加上命名空间:

<li><a href="{% url 'polls:detail' question.id %}">{{question.question_text}}</a></li>

四.在前台进行投票操作

1.构建一个简单的表单提交页

  polls/templates/polls/detail.html

<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 id="choice{{ forloop.counter }}" type="radio" name="choice" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<br />
<input type="submit" name="" id="" value="投票" />
</form>

代码解析:

  form表单提交的url为{%url 'polls:vote' question.id %}, 即表示访问polls/views.py的vote方法,并携带问题id作为参数。

  将问题的相关选项遍历,以单选框显示

  form表单用post方式提交数据

配置url: polls/urls.py

path('<int:question_id>/vote/', views.vote, name='vote'),

2.视图层处理提交结果

  polls/views.py

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .models import Question, Choice
# ...
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "必须选择一个选项",
})
else:
selected_choice.votes += 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

代码解析:

request.POST['choice']接收表单页面提交的数据

将投票次数加1,并更新数据库

3.显示投票结果

  polls/views.py

from django.shortcuts import render, get_object_or_404
# ...
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})

  results.html

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{choice.votes}}</li>
{% endfor %}
</ul> <a href="{% url 'polls:detail' question.id %}">再投一次?</a>

4.优化url和view写法

  将主键id代替question_id
  polls/urls.py

#_*_coding:utf8_*_
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]

使用<pk>代替<question_id>会更加灵活,<pd>代表主键

相应的视图也需要修改成另一种写法,vote方法保持原样,用于比较两种写法的不同

polls/views.py

#_*_coding:utf8_*_
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from .models import Question, Choice class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5] class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html' class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html' def vote(request, question_id):
# ...

  


												

django2.0基础的更多相关文章

  1. 《玩转Django2.0》读书笔记-Django建站基础

    <玩转Django2.0>读书笔记-Django建站基础 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.网站的定义及组成 网站(Website)是指在因特网上根据一 ...

  2. Django2.0使用

    创建项目: 通过命令行的方式:首先要进入到安装了django的虚拟环境中.然后执行命令: django-admin startproject [项目的名称] 这样就可以在当前目录下创建一个项目了. 通 ...

  3. django2.0+连接mysql数据库迁移时候报错

    django2.0+连接mysql数据库迁移时候报错 情况一 错误信息 django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 ...

  4. <-0基础学python.第一课->

    初衷:我电脑里面的歌曲很久没换了,我想听一下新的歌曲,把他们下载下来听,比如某个榜单的,但是一首一首的点击下载另存为真的很恶心 所以我想有没有办法通过程序的方式来实现,结果还真的有,而且网上已经有有人 ...

  5. Android 工程在4.0基础上混淆

    Android现在对安全方面要求比较高了,我今天要做的对apk进行混淆,用所有的第三方工具都不能反编译,作者的知识产权得到保障了,是不是碉堡了. 一,首先说明我这是在4.0基础上进行的. 先看看pro ...

  6. Android程序开发0基础教程(一)

    程序猿学英语就上视觉英语网 Android程序开发0基础教程(一)   平台简单介绍   令人激动的Google手机操作系统平台-Android在2007年11月13日正式公布了,这是一个开放源码的操 ...

  7. swift3.0基础语法

    swift 3.0 基础语法 目录 01-变量和常量 02-运算符 03-可选项 04-条件语句 05-循环 06-字符串 07-元组 08-数组 09-字典 10-对象和类 11-枚举 12-属性 ...

  8. 【转】WF4.0 (基础篇)

    转自:http://www.cnblogs.com/foundation/category/215023.html 作者:WXWinter  ——  兰竹菊梅★春夏秋冬☆ —— wxwinter@16 ...

  9. JAVA思维导图系列:多线程0基础

    感觉自己JAVA基础太差了,又一次看一遍,已思维导图的方式记录下来 多线程0基础 进程 独立性 拥有独立资源 独立的地址 无授权其它进程无法訪问 动态性 与程序的差别是:进程是动态的指令集合,而程序是 ...

随机推荐

  1. 原生js实现头像大屏随机显示

    效果如下图所示: 一.html部分 <div class="myContainer"> <ul> <li class="first" ...

  2. Python基础-列表、元组、字典、字符串(精简解析),全网最齐全。

    一.列表 =====================================================1.列表的定义及格式: 列表是个有序的,可修改的,元素用逗号隔开,用中括号包围的序列 ...

  3. Maven中央仓库地址大全,Maven中央仓库配置示例

    < Maven 中央仓库地址大全 > 在上一篇文章中完成了 < Maven镜像地址大全 >,后来又花了时间又去收集并整理了关于 maven 远程仓库地址,并整理于此,关于 Ma ...

  4. TZOJ 3522 Checker Challenge(深搜)

    描述 Examine the 6x6 checkerboard below and note that the six checkers are arranged on the board so th ...

  5. Leetcode238. Product of Array Except Self除自身以外数组的乘积

    给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输入: [1 ...

  6. 过滤html标签的一个函数

    str_replace(array(' ', '&', '"', ''', '“', '”', '—', '<', '>', '·', '…', '&'), ar ...

  7. Eclipse:Eclipse插件开发全套教程

    分享是美德,作者为Eclipse核心工程师之一,全英文版,有不明白的地方欢迎探讨和咨询. http://www.vogella.com/tutorials/eclipse.html

  8. 《2018年云上挖矿态势分析报告》发布,非Web类应用安全风险需重点关注

    近日,阿里云安全团队发布了<2018年云上挖矿分析报告>.该报告以阿里云2018年的攻防数据为基础,对恶意挖矿态势进行了分析,并为个人和企业提出了合理的安全防护建议. 报告指出,尽管加密货 ...

  9. Django项目:CRM(客户关系管理系统)--34--26PerfectCRM实现King_admin自定义排序

    ordering = ['-qq'] #自定义排序,默认'-id' #base_admin.py # ————————24PerfectCRM实现King_admin自定义操作数据———————— f ...

  10. BZOJ2529: [Poi2011]Sticks

    2529: [Poi2011]Sticks Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 257  Solved: ...