Django学习1

Django下载安装

下载:pip install django==1.11.9

创建项目
	django-admin startproject first_pro
启动项目
	cd first_pro
	python manage.py runserver 127.0.0.1:8001
创建app
	python manage.py startapp app01

关联app需要在项目的配置文件settings.py中添加一个app设置
INSTALL_APPS = [
.....
'app01',   #app名称
]

两个框架模式

MVC
	M:models 数据库相关
	V:views 试图逻辑相关
	C:controller 控制器 url分发 不同的路径找到对应的视图函数
MTV
	M:models 数据库相关
	T:templates 模板, html文件
	V:views 试图逻辑相关
	+ url控制器 不同的路径找到不同的视图函数
MVVM 后面介绍

url 配置

将url写在urls.py文件中的urlpatterns = []中
简单的路由
	from app01 import views
	url(r'^index/$',views.index)
无名分组
	url(r'^index/(/d+)/(/d+)/$',views.index), --- def index(request,n,m)  位置参数
有名分组
	url(r'^index/(?P<year>/d+)/(?P<month>/d+)/$',views.index),--- def index(request,year,month)  关键字参数,位置顺序不影响

视图函数参数默认值
url(r'^index/$',views.index),
url(r'^index/(?P<num>/d+)/',views.index),
	def index(request,num='1'):
		print(num)

路由分发urls

include

在app01,app02目录下创建自己的urls.py
在项目目录下的urls.py中导入include,并分发路由到app01和app02的urls.py

from django.conf.urls import url
from django.conf.urls import include    # 路由分发到每个app
from app01 import views
urlpatterns = [
    url(r'^$', views.base),        # 首页
    url(r'^app01/', include('app01.urls')),  # 分发到app01
    url(r'^app02/', include('app02.urls')),  # 分发到app02
    # http://127.0.0.1:8000/app01/....
]

视图views

请求相关的属性方法 (request -- HttpRequest对象)

def index(request):     # http相关请求信息 -- 封装 -- HttpRequest对象
    if request.method == 'GET':
        print(request.GET)     # 获取GET请求提交的数据
        # print(request.META)  # 请求头的相关信息,一个大字典
        print(request.path)     # /index/路径
        print(request.path_info)  # /index/路径
        print(request.get_full_path())  # /index/?username=dazhuang&password=123  路径+查询信息
        return render(request, 'index.html')
    else:
        # print(request.method)
        print(request.body)  # 获取post请求提交过来的原始数据  b'username=dazhuang'
        print(request.POST)  # 获取POST请求提交的数据

        return HttpResponse('>>>完成')

响应相关的方法

HttpResponse   ---  回复字符串
render   ---   回复一个html页面

redirect  ---  重定向(点会员页面,会让你先登陆/新老网站跳转)
    def login(request):

        if request.method == 'GET':
            return render(request,'login.html')

        else:
            username = request.POST.get('username')
            password = request.POST.get('password')
            if username == 'taibai' and password == 'dsb':
                # return render(request,'home.html')
                return redirect('/home/')  # 重定向,告诉浏览器重新发一个这个路径的请求
            else:
                return HttpResponse('很抱歉,您不是我们的会员...')
	
    # urls.py中 重定向让浏览器请求的新路径
    url(r'^home/', views.home),     # 重定向指定的路径和该路径对应的视图函数
    
    # views.py中 重定向指定的视图函数
    def home(request):
        return render(request,'home.html')
    
    重定向状态码:301 和 302
        301 永久重定向:表示旧地址的资源已经永久移除了(百度也搜索不到了)
        302 临时重定向:表示旧地址的资源还在,仍然可以访问
        浏览器拿到 301 302 状态码都会自动跳转到新的url地址 
    
    百度搜索:html <meta name="keyword" content=".....">

FBV和CBV

FBV --- function base view 基于函数

def home(request):
	print('there is home')
    return render(request,'home.html')

CBV --- class base view 基于类

views.py:
from django.views import View		# 先引入这个!

class LoginView(View):
    # GET请求
    def get(self,request):
        return render(request,'login2.html')
    # POST请求
    def post(self,request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username,password)

        return HttpResponse('登陆成功')
        
urls.py:
url(r'^login2/', views.LoginView.as_view()),	# 路由的写法也发生改变!

CBV通过不同的请求方法找到对应的视图类中的方法的关键 : 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)   # request.method.lower(), 反射!
    else:
        handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

**重写CBV的dispatch方法

class LoginView(View):

    def dispatch(self, request, *args, **kwargs):    # 重写dispatch,在执行真正的dispatch前后搞搞事情
        print('请求来啦')
        # ua = request.META.get('HTTP_USER_AGENT')    # 真正的dispatch分发执行前判断ua
        ret = super().dispatch(request, *args, **kwargs)    # 执行父类真正的dispatch,记得return返回值
        print('到点了,撤了撤了')
        return ret

    # GET请求
    def get(self,request):
        print('get方法执行了')
        return render(request,'login2.html')
    # POST请求
    def post(self,request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username,password)
        # print('post方法执行了')
        return HttpResponse('登陆成功')

FBV加装饰器

# 搞个装饰器
def wrapper(f):
    def inner(*args,**kwargs):
        '''前'''
        print('请求之前')
        ret = f(*args,**kwargs)
        '''后'''
        print('请求之后')
        return ret
    return inner

@wrapper
def home(request):
    return render(request,'home.html')

CBV加装饰器

# 搞个装饰器
def wrapper(f):
    def inner(*args,**kwargs):
        '''前'''
        print('请求之前')
        ret = f(*args,**kwargs)
        '''后'''
        print('请求之后')
        return ret
    return inner

from django.views import View
from django.utils.decorators import method_decorator    # CBV中使用装饰器先导入这个!

# @method_decorator(wrapper,name='get')  # 方式三,在类的头上加,需用name指定要加装饰器的参
class LoginView(View):
    @method_decorator(wrapper)  # 方式二,给dispatch方法加,全部方法都加上了
    def dispatch(self, request, *args, **kwargs):
        print('请求来啦')
        ret = super().dispatch(request, *args, **kwargs)
        print('到点了,走人了')
        return ret

    # GET请求
    # @method_decorator(wrapper)      # 方式一,给单独一个方法加
    def get(self,request): 
        print('get方法执行了')
        return render(request,'login2.html')
原文地址:https://www.cnblogs.com/straightup/p/13417340.html