(2)Django初识之myfirstdjango

Python publisher01 18℃

我不介意忍受孤独,也不害怕日复一日的坚持,会坦白承认自己技不如人,而后虚心学习。我都可以,只要能去到想去的地方。

1、安装

两种方式:
   –命令行安装:pip3 install django==1.11.11
   –在pycharm中安装(导入django模块)
🐷ps:pip3环境有问题用 python -m pip 命令替换 pip3命令或者重新安装pip3,或是更新pip版本:python3 -m pip install –upgrade pip

验证是否安装成功:django-admin
🐷ps:安装出错——> 采用管理员命令行

2、创建Django项目

方式1(命令行创建):
   先前往目标文件夹下
   创建django项目 django-admin startproject 项目名
方式2(pycharm中创建):
   file>>>new project 选择第二个django
🐷ps:需要注意项目名字路径中不能有中文

3、创建app应用

   app概念:一个项目中有许多功能,而app就是这些一个一个不同作用的功能体,就好比项目是一所大学,而app就是大学里的各个系。

方式1(命令行创建):
   进入项目根目录
   创建app应用: python3 manage.py startapp app名
方式2(pycharm中创建):
   创建app应用 python3 manage.py startapp app名 或者Tools–>run managepath–>startapp app名

4、启动服务

启动django项目: python3 manage.py runserver
🐷ps:start your first app by running python manage.py startapp [app_label].


🐷⚠️强调与注意:
   a、用django一定要保证只有一个项目在运行状态;
   b、一定记得清浏览器的缓存(用google浏览器,右击检查);


清除缓存

   c、计算机的名称不能有中文;
   d、以后一个pycharm窗口就是一个项目,不要多个项目放在一个窗口;
   e、项目名不能起中文;
   f、用命令行创建django默认不会自动创建templates文件夹,需要手动自己创建(注意该文件夹路径是否被添加到配置文件中


5、项目及应用目录详解

应用名下
   migrations   数据库迁移(移植)记录相关记录,内容都是由Django自动生成
   admin.py     django后台管理系统配置
   models.py   存放模型表相关,数据模型模块,使用ORM框架,类似于MVC模式下的Model层
   views.py      视图函数相关,执行相应的逻辑代码模块

项目名下
   _ init _.py     模块的配置文件
   settings.py    配置文件
   urls.py      路由与视图函数的映射关系,django项目中的所有页面都需要对其配置url地址
   wsgi.py       (web server gateway interface),服务器网关接口,python应用与web服务器直接通信的接口,拆包解包

templates
   模板文件夹,项目用到的所有的html文件(页面)
manage.py
   项目管理器,与项目交互的命令行工具集的入口,查看支持的所有命令python3 manage.py

6、项目配置文件settings详解

(1) 注意新创建的app需要在配置文件中注册才能生效

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',  🐷简写
        # 'app01.apps.App01Config'  🐷全称
    ]

(2) 在配置文件中暂时禁用csrf中间件,方便表单提交测试。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

(3) 用命令行创建django默认不会自动创建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',
            ],
        },
    },
]

(4) Django 数据库配置
  Django为什么要配置数据库?
    因为Django默认采用的是sqlite3数据库,而我们用Pycharm编写程序时使用的是Pymysql模块和数据库交互的,为了能够简化编写程序的流程,我们需要修改默认数据库配置。

原本使用的sqlite3数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME':os.path.join(BASE_DIR,'db.sqlite3'),
    }
}

创建一个自己的MySQL数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mfd',
        'HOST':'127.0.0.1',
        'POST':3306,
        'USER':'root',
        'PASSWORD':' '
    }
}

(5) 静态文件配置
  用来存放页面样式的css,js,bootstrap
  查找方式:通过/static/匹配到静态文件的根路由 => 根路由管理着static | static1 | static1 三个存放在项目根目录下的文件夹 => 三个文件夹中任意一个存放着index.css即可

STATIC_URL = '/static/'  # 接口前缀  默认情况下这个前缀跟静态文件夹名字一样
# 静态文件配置,规定静态文件可以放入的文件夹
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,'static'),
    os.path.join(BASE_DIR,'static1'),
    os.path.join(BASE_DIR,'static2')
]

7、开启第一个Django项目

(1)总体设计
  Web页面的组件:
    · 一个模板,用于显示通过Python类字典对象传入的信息。
    · 一个视图函数,用于执行针对请求的核心逻辑。视图会从数据库中获取信息,并格式化显示结果。
    · 一个URL模式,将传入的请求映射到对应的视图中,同时也可以将参数传递给视图。
  Django是自底向上处理请求,它首先查找匹配的URL模式,接着调用对应的视图函数(匹配url是自上而下,匹配成功立即执行,在以后url多的情况下要注意顺序),最后将渲染好的数据通过模板展现给用户。

  构建应用的顺序(可依据自身情况创建):
    (1)因为需要一些可以观察的内容,所以先创建基本的模板;
    (2)设计一个简单的URL模式,让Django可以立即访问应用;
    (3)开发一个视图函数原型,然后在此基础上迭代开发。
    使用这个顺序的主要原因是因为模板和URL模式不会发生较大的改变,而应用的核心是视图,所以先快速构建一个基本视图,在此基础上逐步完善,这非常符合测试驱动模型(TDD)的开发模式。

🌸测试驱动模型(TDD)
  测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。
  TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析设计,质量控制量化的过程。
  TDD的重要目的不仅仅是测试软件,测试工作保证代码质量仅仅是其中一部分,而且是在开发过程中帮助客户和程序员去除模棱两可的需求。TDD首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证。

(2)创建URL模式【版本不同,配置路由也有区别,不可一概而论】
🐷ps:这里使用的是django 1.11.17版本
  配置路由的作用是将用户浏览器中URL的路径名映射到应用的不同部分,当用户通过浏览器发出一个请求时,因特网会通过某种方式将主机名与IP地址映射起来,接着客户端在80或其他端口(Django开发服务器默认使用8000端口)与服务器的地址连接起来。

from app01 import views   # 导入创建的app下的视图文件
urlpatterns = [
    url(r'^admin/', admin.site.urls),  # Django自带的登录界面,后面可用来创建超级用户
    url(r'^index/', views.index),  # 配置路由
]

(3)创建视图函数
  在具体应用下的视图文件views.py文件中为请求配置响应函数。
  三种响应:HttpResponse  返回字符串
       render       返回一个html页面
       redirect     重定向

⚠️这里的HttpResponse既可以从django.http导入,又可以从django.shortcuts导入,可以看出http中的字符串响应更丰富:


from django.shortcuts


from django.http

🌰 代码部分,实现响应字符串,响应HTML页面,重定向:

from django.shortcuts import render,HttpResponse,redirect
def view_action1(request):
      return HttpResponse('咸鱼今天努力了没?')   # 响应字符串
def view_action2(request):
      return render(request, 'index.html')   # 响应模板页面
def view_action3(request):
      return redirect('/重定向的路由')

其中render中有两种给前端页面传值的方式:
  🍓第一种是传递一个可迭代对象,这里传递的是一个字典,将值1和值2,通过k1和k2,传递给index.html

        return render(request,'index.html',{'k1': 值1, 'k2': 值2})

  🍓第二种是使用locals( ),将视图函数中所有的局部变量都传递给index.html,也可以传递全局变量globals(),当然这可能会传递一些多余的参数,有点浪费内存。

         return render(request, 'index.html', locals())

  为了进行快速开发,使用伪视图和半伪造的数据能快速验证应用的基本设置是否正确,这种迭代过程非常快速,表明现在可以安全地开始真正的工作。
“HELLO WORLD”伪视图:
views.py中

from django.shortcuts import render,HttpResponse,redirect,render_to_response
from app01.models import User  # 导入模型层实例化出来的对象
def index(request):
    test=User(user='wpp',pwd='111')
    return render_to_response('reg.html',{'tests':[test]})

reg.html中

{% for test in tests %}     <!--注意这里循环的是字典的key-->
<h2>{{ test.user }}</h2>
<p>{{ test.pwd }}</p>
{% endfor %}

启动服务器,网页中显示


web网页效果图


⚠️在这里简单视图使用的是render(),伪视图使用的是render_to_response(),但实际开发依自己情况看。
  接下来详解一下使用render和render_to_reponse()
🍓首先使用原生的方式从获取数据到向客户端返回HTTP响应需要遵循以下步骤:
    · 向数据库查询所有用户信息
    · 载入模板文件
    · 为模板创建上下文字典
    · 将上下文传递给模板
    · 将模板渲染到HTML中
    · 通过HTTP响应返回HTML

⚠️注意有坑(版本问题)
def index(request):
    test = User.objects.all()
    t = loader.get_template('reg.html')
    c=Context({'tests':test})
    return HttpResponse(t.render(c))

运行上面展示页面,结果…


令人崩溃的黄页

解读一下报错信息:context must be a dict rather than Context.(上下文必须是字典而不是上下文???黑人问号,既拗口又矛盾)对啊,我传的是字典,为什么还会报错呢,那就分析一下源码。
Context源码:

def make_context(context, request=None, **kwargs):
    """
    Create a suitable Context from a plain dict and optionally an HttpRequest.
    """
    if context is not None and not isinstance(context, dict):
    ⚠️找到报错点,这里要求传给context的参数必须是字典
        raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
    if request is None:
        context = Context(context, **kwargs)
    else:
        # The following pattern is required to ensure values from
        # context override those from template context processors.
        original_context = context
        context = RequestContext(request, **kwargs)
        if original_context:
            context.push(original_context)
⚠️返回出去的就直接是context或者是基子类RequestContext实例对象
    return context

那么问题来了,返回给谁呢,而且context的参数是谁传给他的呢??
经过一番研究,从自己写的代码中抽丝剥茧,发现返回给render,那render又是哪里来的呢?是Template.render(),是Template类中的一个方法,那就看一下Template的源码:

import django.template.backends.django  # 导入Django,查看源码
class Template(object):
    def __init__(self, template, backend):
        self.template = template
        self.backend = backend
    @property
    def origin(self):
        return self.template.origin
⚠️这里render传入参数给context,再用make_context对传入的字典进行处理,直接返回context,就说明这里context已经封装好了!!!!!我们只要直接传字典进去就好了!!!
    def render(self, context=None, request=None):
        context = make_context(context, request, autoescape=self.backend.engine.autoescape)
        try:
            return self.template.render(context)
        except TemplateDoesNotExist as exc:
            reraise(exc, self.backend)

🌸⚠️上面这段代码就解释了为什么render要传字典!!
修改代码:

def index(request):
    test = User.objects.all()
    t = loader.get_template('reg.html')
    return HttpResponse(t.render({'tests':test}))

终于。。


来之不易的页面

总结:版本是个坑,随着版本的更新,很多方法被不断的封装,集成,所以在以后的学习中要注意版本问题,也要多去研究研究源码!

🍓 创建快捷方式 render_to_response()和render()
  从(获取数据,渲染到模板,返回响应)这一系列过程是复杂的而且由于加载模板、填充 context 、将经解析的模板结果返回为 HttpResponse 对象这一系列操作实在太常用了,Django 提供了一条仅用一行代码就完成所有这些工作的捷径。该捷径就是位于 django.shortcuts 模块中名为 render_to_response() 的函数和render()函数。大多数时候,你将使用这两个函数,而不是手动加载模板、创建 Context 和 HttpResponse 对象。
  🐷render_to_response()和render()返回的是HttpResponse对象

  【1】 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)

  需要的参数有:request,HTML模板页面名,context传参(这里必须传字典[往上看翻车例子,讲了为什么要传字典]或局部变量或全局变量)

  【2】render_to_response( )源码:传一个或两个参数

def render_to_response(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, using=using)
    return HttpResponse(content, content_type, status)

  需要的参数有:HTML模板页面名,context参数

  【3】render_to_response( )和render( )的区别:
    区别一:
    自django1.3开始:render()方法是render_to_response的一个崭新的快捷方式,render_to_response会自动使用RequestContext。而render必须coding出来,这是最明显的区别,当然前者更简洁。

return render_to_response('index.html',{'user': 'wpr', 'pwd': 123})
return render(request, 'index.html', {'user': 'wpr', 'pwd': 123})

    区别二:
    如果都不传递data,只返回静态模板的话,render需要传入request,而render_to_response只需传入静态模板就行了:

def index(request):
    return render(request,'index.html')   
    return render_to_response('index.html')

🦌对于向作者这样的懒人,把极简主义发挥到了极致,而且经常忘记request的人来说,还是render_to_response好用….

(3)创建模板
  后端传递给前端模板的变量是特殊的python字典,称为上下文(context)。
  模板其实就是HTML前端页面,里面有模板语言,比如变量标签{{ }},里面是用于显示对象的内容,在变量标签中可以使用过滤器(过滤器是函数),它能在标签中立即对变量进行处理,只要在变量的右边插入一个管道符号(“|”)。此外还有块标签{%  %},它用于向html模板中插入如循环或判断这样的逻辑。

{% for test in tests %}
<h2>{{ test.user }}</h2>
<p>{{ test.pwd }}</p>
{% endfor %}

🐷HTML模板文件是放在templates文件夹下的。


Myfirstdjango

# urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
]
# views.py
def index(request):
    test = User.objects.all()
    return render(request, 'index.html', {'tests':test})
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% for test in tests %}
    <h2>{{ test.user }}</h2>
    <p>{{ test.pwd }}</p>
{% endfor %}
</body>
</html>

生活要有仪式感


myfirstdjango

转载请注明:Python量化投资 » (2)Django初识之myfirstdjango

喜欢 (0)or分享 (0)