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',#安全机制
返回一个字典 获取值要把一个安全机制注释才能过
视图函数
视图函数
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/') #重定向路径
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('登录成功')
图解
装饰器
有三种方式
在类上面必须指定请求方法
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#静态文件路径别名