Django-MVT

(1)查看python版本号:

python -m django --version

(2) 创建Django项目

django-admin startproject mysite

(3)测试开发服务器是否成功

Desktop\bncDjango\mysite>python manage.py runserver

Django 自带一个用纯 Python 写的轻量级的 Web 服务器。为了让你能快速的开发出想要的东西,因为你不需要进行配置生产级别的服务器(比如 Apache)方面的工作,除非你已经准备好投入生产环境了。千万不要 将这个服务器用于和生产环境相关的任何地方。这个服务器只是为了开发而设计的。(我们在 Web 框架方面是专家,在 Web 服务器方面并不是。)

(4)创建应用模块

python manage.py startapp polls

Application definition

INSTALLED_APPS = [

'django.contrib.admin', # 管理员站点

'django.contrib.auth', # 认证授权系统

'django.contrib.contenttypes', # 内容类型框架

'django.contrib.sessions', # 会话框架

'django.contrib.messages', # 消息框架

'django.contrib.staticfiles', #管理静态文件的框架

'polls', # 投票模块

]

(5)polls模型下编辑视图view


from django.shortcuts import render

Create your views here.

from django.http import HttpResponse

def index(request):

return HttpResponse("Hello,this is my frist polls index.")

(6)polls模块下映射url


from django.urls import path
from . import views

urlpatterns = [

path('', views.index,name='index'),

]

(7)mysite主模块下配置url


from django.contrib import admin
from django.urls import path,include # 注意导入include模块

urlpatterns = [

path('polls/', include('polls.urls')), # 配置polls子模板url,支持正则

path('admin/', admin.site.urls),

]

(8)网页查询http://localhost:8000/polls/

(9)数据库配置与迁移

DATABASES = {

'default': {

# 'django.db.backends.sqlite3',

# 'django.db.backends.postgresql',

# 'django.db.backends.mysql',

# 'django.db.backends.oracle'

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

},

# MySQL数据库配置

# 'mysql': {

# 'ENGINE': 'django.db.backends.mysql',

# 'NAME': 'all_news', # 数据库名

# 'USER': 'root',

# 'PASSWORD': 'root',

# 'HOST': '127.0.0.1',

# 'PORT': '3306',

# }

}

python manage.py migrate

(10)编写模型M


from django.db import models

Create your models here.

class Question(models.Model):

question_text = models.CharField(max_length=200)

pub_data = models.DateField('date published')

def __str__(self):
return self.question_text

class Choice(models.Model):

question = models.ForeignKey(Question,on_delete=models.CASCADE)

choice_text = models.CharField(max_length=200)

votes = models.IntegerField(default=0)

def __str__(self):
return self.choice_text

(11)激活模型

为模型的改变生成迁移文件

python manage.py makemigrations polls

另一种查看,选择执行接收一个迁移的名称,然后返回对应的 SQL

python manage.py sqlmigrate polls 0001

应用数据库迁移

python manage.py migrate

(12)全自动后台管理页面

12.1 创建一个能登录管理页面的用户,均为admin

python manage.py createsuperuser

12.2 启动开发服务器:

python manage.py runserver

http://127.0.0.1:8000/admin/login/?next=/admin/

12.3 进入站点

12.4 管理页面中加入配置应用


from django.contrib import admin

Register your models here.

from .models import Question,Choice

admin.site.register(Question)

admin.site.register(Choice)

(13)编写更多视图

13.1 polls下的views



from django.shortcuts import render

from django.http import HttpResponse

问题索引页

def index(request):

return HttpResponse("Hello,this is my frist polls index.")

问题详情页

def detail(request,question_id):

return HttpResponse("You're looking at question %s." % question_id)

问题结果页

def results(request,question_id):

return HttpResponse("You're looking at the results of question %s." % question_id)

投票处理器

def vote(request,question_id):

return HttpResponse("You're voting on question %s." % question_id)

13.2 polls下的urls记得添加命名空间


from django.urls import path
from . import views
app_name = 'polls' #添加命名空间
urlpatterns = [
# ex: /polls/
path('', views.index,name='index'),
# ex: /polls/5/
path('/', views.detail, name='detail'),
# ex: /polls/5/results/
path('/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('/vote/', views.vote, name='vote'),
]

13.3 查询数据库信息并页面显示


# 问题索引页
def index(request):
latest_question_list = Question.objects.order_by('pub_data')[:3]
output = '
'.join([q.question_text for q in latest_question_list])
HttpResponse(template.render(context,request))
return HttpResponse(output)

(14)编写模板T

14.1 在mysite下创建templates,并创建polls文件夹下创建index.html

投票页面

{% if latest_question_list %}

{% else %}

No polls are available.

{% endif %}

可以修改为(常用).想改成 polls/specifics/12/ ,你不用在模板里修改任何东西(包括其它模板),只要在 polls/urls.py 里稍微修改一下就行:



{% for question in latest_question_list %}

  • {{ question.question_text }}
  • {% endfor %}

    14.2 在mysite的settings修改DIRS


    TEMPLATES = [
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR,'template/')],
    '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',
    ],
    },
    },
    ]

    14.3 polls/views.py 修改


    from django.shortcuts import render
    from django.http import HttpResponse
    from django.template import loader

    from polls.models import Question

    问题索引页

    def index(request):

    latest_question_list = Question.objects.order_by('pub_data')[:5]

    # output = '
    '.join([q.question_text for q in latest_question_list])

    template = loader.get_template('polls/index.html')

    context = {

    'latest_question_list': latest_question_list,

    }

    return HttpResponse(template.render(context,request))

    进一步可以修改为(常用):


    # 问题索引页
    def index(request):
    latest_question_list = Question.objects.order_by('pub_data')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request,'polls/index.html',context)

    14.4 在浏览器访问 "/polls/" 查看:

    (15)查看详细页面

    15.1 polls下views.py


    from django.http import Http404

    问题详情页

    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,'question_id':question_id})

    优化后的算法(常用)


    from django.shortcuts import render,get_object_or_404

    问题详情页

    def detail(request,question_id):

    question = get_object_or_404(Question, pk=question_id)

    return render(request, 'polls/detail.html', {'question': question,'question_id':question_id})

    15.2 template下detail.html

    详细问题页面

    {{ question.question_text }}

      {% for choice in question.choice_set.all %}

    • {{ choice.choice_text }}
    • {% endfor %}

    15.3 运行结果

    (16)polls/detail.html详细页面添加一个表单form

    {{ question.question_text }}

    {% if error_message %}

    {{ error_message }}

    {% endif %}

    {% csrf_token %}
    {% for choice in question.choice_set.all %}

    {{ choice.choice_text }}


    {% endfor %}

    • 每个单选按钮的 value 属性是对应的各个 Choice 的 ID。每个单选按钮的 name"choice" 。这意味着,当有人选择一个单选按钮并提交表单提交时,它将发送一个 POST 数据 choice=# ,其中# 为选择的 Choice 的 ID。这是 HTML 表单的基本概念。

    • 我们设置表单的 action{% url 'polls:vote' question.id %} ,并设置 method="post" 。使用 method="post"是非常重要的,因为这个提交表单的行为会改变服务器端的数据。当你需要创建一个改变服务器端数据的表单时,请使用``method="post"` 。这不是 Django 的特定技巧;这是优秀的网站开发技巧。

    • forloop.counter 指示 for 标签已经循环多少次。

    • 由于我们创建一个 POST 表单(它具有修改数据的作用),所以我们需要小心跨站点请求伪造。 谢天谢地,你不必太过担心,因为 Django 已经拥有一个用来防御它的非常容易使用的系统。 简而言之,所有针对内部 URL 的 POST 表单都应该使用{% csrf_token %} 模板标签。

    (17) polls/views.py 视图编辑


    # 投票处理器
    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': "You didn't select a choice.",})
    else:
    selected_choice.votes +=1
    selected_choice.save()
    return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

    • request.POST 是一个类字典对象,让你可以通过关键字的名字获取提交的数据。 这个例子中, request.POST['choice'] 以字符串形式返回选择的 Choice 的 ID。 request.POST 的值永远是字符串。
    • 如果在 request.POST['choice'] 数据中没有提供 choice , POST 将引发一个 KeyError 。上面的代码检查 KeyError ,如果没有给出 choice 将重新显示 Question 表单和一个错误信息。
    • 在增加 Choice 的得票数之后,代码返回一个 HttpResponseRedirect 而不是常用的 HttpResponseHttpResponseRedirect 只接收一个参数:用户将要被重定向的 URL。构造函数中使用 reverse()函数。这个函数避免了我们在视图函数中硬编码 URL。重定向的 URL 将调用 'results' 视图来显示最终的页面。

    (18) 重定向results.html


    from django.shortcuts import get_object_or_404, render

    def results(request, question_id):

    question = get_object_or_404(Question, pk=question_id)

    return render(request, 'polls/results.html', {'question': question})

    (19)通用视图,代码重构

    19.1 detail() 视图几乎一模一样。唯一的不同是模板的名字。


    # 问题索引页
    def index(request):
    latest_question_list = Question.objects.order_by('pub_data')[:5]
    return render(request,'polls/index.html',{'latest_question_list': latest_question_list})

    问题详情页

    def detail(request,question_id):

    question = get_object_or_404(Question, pk=question_id)

    return render(request, 'polls/detail.html', {'question': question,'question_id':question_id})

    问题结果页

    def results(request,question_id):

    question = get_object_or_404(Question, pk=question_id)

    return render(request, 'polls/results.html', {'question': question})

    19.2 创建一个 polls/results.html 模板

    {{ question.question_text }}

      {% for choice in question.choice_set.all %}

    • {{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}
    • {% endfor %}

    Vote again?

    19.3 通用视图系统

    通用视图将常见的模式抽象化,可以使你在编写应用时甚至不需要编写Python代码。将我们的投票应用转换成使用通用视图系统,这样我们可以删除许多我们的代码。我们仅仅需要做以下几步来完成转换,

    • 转换 URLconf。
    • 删除一些旧的、不再需要的视图。
    • 基于 Django 的通用视图引入新的视图

    1 改良URLconf

    打开 polls/urls.py 这个 URLconf 并将它修改成:路径字符串中匹配模式的名称已经由 <question_id> 改为 <pk>


    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'),

    ]

    2 改良视图

    删除旧的 index, detail, 和 results 视图,并用 Django 的通用视图代替。打开 polls/views.py 文件,并将它修改成:


    from django.http import HttpResponseRedirect
    from django.shortcuts import get_object_or_404, render
    from django.urls import reverse
    from django.views import generic

    from .models import Choice, Question

    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):

    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': "You didn't select a choice.",

    })

    else:

    selected_choice.votes +=1

    selected_choice.save()

    return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

    • 每个通用视图需要知道它将作用于哪个模型。 这由 model 属性提供。
    • DetailView 期望从 URL 中捕获名为 "pk" 的主键值,所以我们为通用视图把 question_id 改成 pk

    19.4 运行程序

    主页面

    子页面

    详情页面

    (20)自动化测试

    20.1 测试的策略

    • 测试驱动:写代码之前先写测试。「测试驱动」的开发方法只是将问题的描述抽象为了 Python 的测试样例。
    • 更普遍的情况是,一个刚接触自动化测试的新手更倾向于先写代码,然后再写测试。
    • 如果你才写了几千行 Python 代码,选择从哪里开始写测试确实不怎么简单。如果是这种情况,那么在你下次修改代码(比如加新功能,或者修复 Bug)之前写个测试是比较合理且有效的。

    20.2 第一个测试

    需求:我们的要求是如果 Question 是在一天之内发布,was_published_recently()方法将会返回True,然而现在这个方法在Questionpub_date` 字段比当前时间还晚时也会返回 True

    编写测试代码:


    from django.test import TestCase

    Create your tests here.

    from django.utils import timezone

    from .models import Question

    class QuestionModelTests(TestCase):

    def test_was_published_recently_with_future_question(self):

    """

    was_published_recently() returns False for questions whose pub_date

    is in the future.

    """

    time = timezone.now() + datetime.timedelta(days=30)

    future_question = Question(pub_date=time)

    self.assertIs(future_question.was_published_recently(), False)

    运行代码:$ python manage.py test polls

    测试结果:

    • python manage.py test polls 将会寻找 polls 应用里的测试代码
    • 它找到了 django.test.TestCase 的一个子类
    • 它创建一个特殊的数据库供测试使用
    • 它在类中寻找测试方法——以 test 开头的方法。
    • test_was_published_recently_with_future_question 方法中,它创建了一个 pub_date 值为 30 天后的 Question 实例。
    • 接着使用 assertls() 方法,发现 was_published_recently() 返回了 True,而我们期望它返回 False

    测试系统通知我们哪些测试样例失败了,和造成测试失败的代码所在的行号。

    (21)静态文件(图片/脚本/样式)

    对于小项目来说,静态文件随便放在哪,只要服务程序能够找到它们就行。然而在大项目中,处理不同应用所需要的静态文件的工作就显得有点麻烦了。这就是 django.contrib.staticfiles 存在的意义

    创建的 static 文件夹中创建 polls 的文件夹,再在 polls 文件夹中创建一个名为 style.css 的文件。样式表路径应是 polls/static/polls/style.css。因为 AppDirectoriesFinder 的存在,你可以在 Django 中简单地使用以 polls/style.css 的形式引用此文件,类似你引用模板路径的方式。

    li a {
    color: green;
    }

    polls的index.html引用

    投票页面
    {% load static %}

    添加图片

    我们会创建一个用于存在图像的目录。在 polls/static/polls 目录下创建一个名为 images 的子目录。在这个目录中,放一张名为 background.gif 的图片。换言之,在目录 polls/static/polls/images/background.jpg 中放一张图片。


    body {
    background: white url("images/background.gif") no-repeat;
    }

    更多关于设置和框架的资料,参考 静态文件解惑静态文件指南部署静态文件 介绍了如何在真实服务器上使用静态文件。

    (22) 编写第一个django应用

    22.1 polls/admin定义后台表单,列表为字段显示顺序


    from django.contrib import admin

    Register your models here.

    from .models import Question,Choice

    class QuestionAdmin(admin.ModelAdmin):

    fieldsets = [

        # ('问题内容', {'fields': ['question_text']}),
    # ('发布时间', {'fields': ['pub_data']}),
    # ]
    # fields = ['pub_data', 'question_text']
    list_display = ('question_text', 'pub_data')

    admin.site.register(Question, QuestionAdmin)

    class ChoiceAdmin(admin.ModelAdmin):

    # fields = ['question','choice_text', 'votes']

    list_display = ('question','choice_text', 'votes')

    admin.site.register(Choice, ChoiceAdmin)

    22.2 字段过滤器


    class QuestionAdmin(admin.ModelAdmin):
    list_display = ('question_text', 'pub_data')
    list_filter = ['pub_data'] # 过滤器
    admin.site.register(Question, QuestionAdmin)

    22.3 自定义后台界面与风格

    • 打开你的设置文件(mysite/settings.py,牢记),在 TEMPLATES 设置中添加 DIRS 选项:

    • templates 目录内创建名为 admin 的目录,随后,将存放 Django 默认模板的目录(django/contrib/admin/templates)内的模板文件 admin/base_site.html 复制到这个目录内。Django 的源文件在哪里?$ python -c "import django; print(django.path)"

    • 接着,用你站点的名字替换文件内的 [](https://docs.djangoproject.com/zh-hans/2.2/intro/tutorial07/#id1){{ site_header|default:_('Django administration') }}(包含大括号)。完成后,你应该看到如下代码:


    {% block branding %}

    Polls Administration

    {% endblock %}

    笔记6:Django基础的更多相关文章

    1. 【笔记】Django基础(一)

      ---恢复内容开始--- [笔记]Django基础(一) oldboy Django  一 关于Python框架的本质 1. HTTP协议消息的格式: 请求(request) 请求方法 路径 HTTP ...

    2. 1.django笔记之django基础

      一.django简介 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的软件设计模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内 ...

    3. 老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分

      老师的blog整理 python基础部分: 宝哥blog: https://www.cnblogs.com/guobaoyuan/ 开哥blog: https://home.cnblogs.com/u ...

    4. 【笔记】AJAX基础

      [笔记]AJAX基础 Django AJAX  知识储备:JSON 什么是 JSON JSON 是轻量级的文本数据交换格式 JSON 独立于语言和平台.JSON 解析器和 JSON 库支持许多不同的编 ...

    5. 图解Python 【第十二篇】:Django 基础

      本节内容一览表: Django基础:http://www.ziqiangxuetang.com/django/django-tutorial.html 一.Django简介 Django文件介绍:ht ...

    6. 老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分

      老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分   老师的blog整理 python基础部分: 宝哥blog: https://www.cnblogs.com/gu ...

    7. js学习笔记:webpack基础入门(一)

      之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

    8. [Java入门笔记] 面向对象编程基础(二):方法详解

      什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

    9. Python之路-(js正则表达式、前端页面的模板套用、Django基础)

      js正则表达式 前端页面的模板套用 Django基础 js正则表达式: 1.定义正则表达式 /.../  用于定义正则表达式 /.../g 表示全局匹配 /.../i 表示不区分大小写 /.../m ...

    10. Django 基础教程

      Django 基础教程 这是第一篇 Django 简介 »  Django 是由 Python 开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站! 你一定可以学会,Django 很简单 ...

    随机推荐

    1. luoguP5227 [AHOI2013]连通图(线性基做法)

      题意 神仙哈希做法. 随便找个生成树,给每个非树边赋一个值,树边的值为所有覆盖它的边的值得异或和. 删去边集使得图不联通当且即当边集存在一个子集异或和为0,可以用线性基. 证明的话好像画个图挺显然的 ...

    2. 【day08】PHP

      一. 函数 1.函数:封装的,可以重复使用的完成特定功能的代码段. 2.函数分类:   (1)系统函数   (2)自定义函数 3.自定义函数   (1)格式   function 函数名称([参数[= ...

    3. Win10安装 oracle11g 出现INS-13001环境不满足最低要求解决方法

      Win10安装 oracle11g 出现INS-13001环境不满足最低要求 首先,打开你的解压后的database文件夹,找到stage,然后cvu,找到cvu_prereq.xml文件,用note ...

    4. 【转】ServletContext介绍及用法

      1.1.  介绍 ServletContext官方叫servlet上下文.服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象.这个对象全局唯一,而且工程内部的所有servl ...

    5. Paper | Residual Dense Network for Image Super-Resolution

      目录 Residual dense block & network 和DenseNet的不同 摘要和结论 发表在2018年CVPR. 摘要和结论都在强调方法的优势.我们还是先从RDN的结构看起 ...

    6. JS中的undefined,null,"",0,'0'和false

      ){ console.log(); } '){ console.log() } '){ console.log() } if(false==0.0){ console.log() } if(false ...

    7. ES6-Symbol.iterator 迭代器

      一个数据结构只要部署了Symbol.iterator属性就能使用 for...of遍历 与 ...运算符 操作 Object身上没有Symbol.iterator,当直接使用时会报错 let obj ...

    8. flash判断,及安装注意

      使用下面方法判断flash版本 function flashChecker() { var hasFlash = 0; //是否安装了flash var flashVersion = 0; //fla ...

    9. 转:xcode项目打不开:incompatible project version问题

      这个是xcode版本对应不上,不一定要修改版本,我们修改记录版本的文件里面的版本号就行了. 低版本xcode打开高版本xcode项目或库工程的时候就会出现,打不开的问题 解决 1可以重建创建工程,将文 ...

    10. Wireshark使用入门

      目录 1. Wireshark介绍 1.1 客户端界面 1.2 Display Filter 的常用方法 1.3 界面上一些小TIPS 2. 使用Wireshark分析TCP三次握手过程 2.1 三次 ...