django入门

下载安装django

pip3 install django==1.11.23

django创建项目

命令行

下载安装django

pip3 install django==1.11.23 
pip3 install django==1.11.23 http://mirrors.aliyun.com/pypi/simple/ 

创建项目
python36 manage.py runserver#开启django项目
python36 manage.py runserver 80 把端口号改成默认80
python36 manage.py runserver 0.0.0.0:80 其他人就可以访问了

创建app
python manage.py startapp app名称
指令船舰app需要的配置
项目的settings配置文件中,installapps的列表,添加一个app名称作为配置 
pycharm 创建完app之后,
如果在向创建新的app,需要指定创建app命令配置,
pycharm会自动配置app路径

djnago的py文件的分类

1.manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件。
2.settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
3.urls.py ----- 负责把URL模式映射到应用程序w。
4.wsgi.py ---- runserver命令就使用wsgiref模块做简单的web server,后面会看到renserver命令,所有与socket相关的内容都在这个文件里面了,目前不需要关注它。

子项目的文件分类

views是写视图函数 视图类 代码逻辑

models是数据库的源 写与数据库相关的的

templatses 是模板 放置html xml等网络文件

wsgi用于书写socket

django基本操作

request对象 封装了所有请求  
request.method是当前请求方法 
````````````````````````````````````
.post 获取post请求的数据#请求体
.get 获取get请求的数据#问号以后的值
request.GET.get('pwd') 获取get 字典的值
request.POST.get('pwd')获取post 字典的值
post。get(“键”)取得的值是一个字符串
·······································

`````````````````````````````````````````````
注意'django.middleware.csrf.CsrfViewMiddleware',#安全机制

返回一个字典 获取值要把一个安全机制注释才能过

1569323222768

视图函数

视图函数
def articles(request,year,month): # 位置参数(形参) 2019 9
 print(year,type(year)) #2019 <class 'str'>  
#匹配出来的所有数据都是字符串
   print(month)
 return HttpResponse(year+'年'+ month +'月' +'所有文章')
 # 无名分组参数
    url(r'^articles/(\d+)/(\d+)/', views.articles), #articles/2019/9/

# 有名分组参数
url(r'^articles/(?P<xx>\d+)/(?P<oo>\d+)/', views.articles), #articles/2019/9/
#xx=2019  oo=9  关键字传参

def articles(request,oo,xx):  # 关键字传参 2019  9
    print(xx,type(xx)) #2019 <class 'str'>  #匹配出来的所有数据都是字符串
    print(oo)
    return HttpResponse(xx+'年'+ oo +'月' +'所有文章')

有名分组参数

# 有名分组参数
url(r'^articles/(?P<xx>\d+)/(?P<oo>\d+)/', views.articles), #articles/2019/9/
#xx=2019  oo=9  关键字传参

def articles(request,oo,xx):  # 关键字传参 2019  9
    print(xx,type(xx)) #2019 <class 'str'>  #匹配出来的所有数据都是字符串
    print(oo)
    return HttpResponse(xx+'年'+ oo +'月' +'所有文章')

无名分组参数

 # 无名分组参数
url(r'^articles/(\d+)/(\d+)/', views.articles), #articles/2019/9/
正则分组/(\d+)/(\d+)/会把匹配的  一一对应单独存储一个变量
(\d+)正则贪婪 满足一个或多个整数

具体示例

例如
html写法
<a href="/articles/2019/9">2019.9</a>#会把路径进行正则匹配 
#(要一一对应)
url(r"^articles/(\d+)/(\d+)/",views.articles),
#匹配的时候,返回对应的匹配的内容,
#articles是返回路径 后面匹配两个参数(正则匹配路径)

视图函数(request请求)补充

request是wsgirequest实例化的对象
1.print(request)打印出来的是--str--的返回值
requesrt这个对象含有————str————
#返回的都是字符串
2.print(request.path) #/home/  纯路径

3.print(request.path_info) #/home/  纯路径

4.print(request.get_full_path()) #/home/?a=1&b=2  全路径(不包含ip地址和端口)

5.print(request.body)  能够拿到请求数据部分的数据(post,get没有),get数据的内容在url里

6.print(request.META)
是一个Python字典,包含了所有本次HTTP请求的Header信息
查看需要在线json转换
user-agent返回

7.print(request.GET)返回get请求的数据类似字典的值
8.print(request.POST)返回get请求的数据类似字典的值
访问其他路径服务端会返回状态信息(状态码)

response响应的三个方法

三个方法都需要模块的引用
底部都有一个httpResponse 把字符串传入页面
form django.shortcuts import render,HttpResponse,redirect
1.HTTPResponse('字符串')#传入一个字符串 向浏览器返回一个页面
render 和redirect都是通过httpresponse传递给浏览器 

2.render(request,'xx.html')返回浏览器一个xx.html
#模板渲染 模板就是html页面 渲染就是字符串替换
'''
示例
'''
#home.html页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>24期官网</h1>
<h2>{{ namxx }}</h2>
</body>
</html>


#views视图.py (render有第三个参数是html传参使用)
def home(request):
    name = 'chao'
    return render(request, 'home.html',		{'namxx':name,})  #模板渲染(先把字符串替换了),这是在回复给浏览器之前做的事情
·······································

3.redirect 重定向

用法 redirect(路径) 示例:redirect('/index/')

会返回浏览器3xx一个重定向 返回一个redirect('/index/')路径

redirect示例
浏览器访问/index/#例如127.0.0.1/index/
urls.py
from django.conf.urls import url
from django.contrib import admin
from Django_test import views#引用 视图函数模块
urlpatterns = [
   url(r'^index/', views.index),
]
def home(request):
    print('xxxxx')
 	return redirect('/index/') #重定向路径

1569402912947

FBV和CBV 视图(视图函数和视图类)

FBV是视图函数

def 函数名(request):
    函数体#进行判断
    return 要一个返回值返回给浏览器

CBV是视图类

urls写法

url(r'^login',views.LoginView.as_view())
1.加载到这一句的时候LoginView这个类直接调用执行类方法,LoginView没有as_view方法 去父类View去寻找这个方法
2.执行完之后返回一个view方法名
3.相当于视图函数#执行url(r'^login',views.view)
4.等待源码调用view方法(函数)

views视图类的写法

from django.views import View#引用View方法
 class LoginView(View):#创建一个类 继承父类view
    def get(self,request):##处理get请求直接定义get方法,不需要自己判断请求方法了,源码中用dispatch方法中使用了反射来处理的
        print('小小小小')
        return render(request,'login.html')
    def post(self,request)

view源码简化分析

执行步骤:
1.加载类名去调用执行as_view方法#views.loginview.as_view()#as_view
2.as_view返回一个view方法名
3.urls执行view方法
4.寻找到as_view函数里有view方法self = cls(**initkwargs)#实例化一个对象cls对应的就是 LoginView视图类
5. 继续往下执行return self.dispatch(request, *args, **kwargs)#这时self是LoginView视图类的实例化对象 去LoginView类中去寻找dispatch方法
6.LoginView视图类没有找到去对应的父类View去寻找
dispatch方法
7.找到http_method_names对应属性里面有各类方法
8.请求的方法名在这个属性中继续往下执行反射
9.利用反射去寻找对应的方法,如果找不到对应方法执行第三个参数报错
#注意
 getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405


父类view
class View(object):

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    @classonlymethod
    def as_view(cls, **initkwargs):
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))
      2.#as_view里面有一个view方法
       	def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            3.#实例化cls方法(就是LoginView视图类) 拿到自己类的对象
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
        4.#执行到这发现 类调用一个方法 去视图类(LoginView)寻找dispatch方法,没有这个方法就去继承的父类去寻找 执行
        view.view_class = cls
        view.view_initkwargs = initkwargs

        update_wrapper(view, cls, updated=())

        update_wrapper(view, cls.dispatch, assigned=())
        return view 1.#返回一个view方法
    """
   dispatch方法
    """
5.找到dispatch方法执行
def dispatch(self, request, *args, **kwargs):
    #request.method.lower()取得请求对应的方法 方法名都是大写的所以需要小写对应
    #http_method_names去LoginView类去找,找不到去在源码中寻找(也就是继承的父类)
    if request.method.lower() in self.http_method_names:
        #请求的方法名在这个http_method_names属性中继续往下执行反射 
        #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        #利用反射去寻找对应的方法
        #getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)
#为什么第三个参数返回405
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
getattr 第二个参数找不到就执行第三个参数
'''http_method_not_allowed方法'''#为什么第三个参数返回405

def http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning(
        'Method Not Allowed (%s): %s', request.method, request.path,
        extra={'status_code': 405, 'request': request}
    )
    return http.HttpResponseNotAllowed(self._allowed_methods())

想法 在进行分发操作之前想要执行一些命令

自己重构父类的时候必须执行父类的分发操作

如果没有这个方法他会报错

(重构父类dispatch方法)

from django.views import View
class LoginView(View):
    def dispatch(self,request,*args,**kwargs):
        print("xxx请求来了")
    ret=super(LoginView,self).dispatch(request,*args,**)
   重构父类(view)的dispatch方法
 #def dispatch(self, request, *args, **kwargs):
  # if request.method.lower() in self.http_method_names:
    #handler = getattr(self,request.method.lower(),
 	#self.http_method_not_allowed)
# else:
  #handler = self.http_method_not_allowed
  #return handler(request, *args, **kwargs)
#执行对应方法 获得返回值 

    print("执行结束")
    return ret
#相当于执行return handler(request, *args, **kwargs)
    def get(self,request):
        print('xxxx')
        return render(request,"login.html")
    def post(self,request):
        print(request.POST)
        return HttpResponse('登录成功')

图解

1569416028460

装饰器

有三种方式

在类上面必须指定请求方法

from django.utils.decorators import method_decorator
#必须引用django封装的装饰器
def wrapper(func):
    def inner(*args, **kwargs):
        print(11111)
        ret = func(*args, **kwargs)
        print(22222)

        return ret

    return inner

@method_decorator(wrapper,name='get')#第一种放松
class LoginView(View):
    def get(self,request):
        print('xxxx')
        return render(request,"login.html")

    @method_decorator(wrapper) #方式2
    def dispatch(self, request, *args, **kwargs):
        print('xx请求来啦!!!!')

        ret = super().dispatch(request, *args, **kwargs)

        print('请求处理的逻辑已经结束啦!!!')
        return ret

    @method_decorator(wrapper)#方式3
    def post(self,request):
         print(request.POST)
         return HttpResponse('登录成功')

App项目的创建

新建APP

python manage.py   startapp  app名称

注册APP

在settings中

INSTALLED_APPS = [
    'app01',  
    'app01.apps.App01Config',  # 推荐写法
]

django的setting解释

from 项目名 import settings 局部配置文件
from django.conf import sttings 整个django的配置文件(全局配置)
#注意
如果局部配置文件和全局配置重复 使用局部配置文件的配置
以后引用可以使用全局配置 以防引用配置的时候报错(局部没有配置的时候)
调用配置文件
print(settings.STATIC_URL)获取对应的STATIC_UR的值L#静态文件路径别名

模板渲染

模板渲染

posted @ 2019-11-22 18:00  strawberry*  阅读(209)  评论(0编辑  收藏  举报