Django

Django简介

前面已经详细介绍过flask框架了(
https://blog.csdn.net/nie7342/article/details/101122347
https://blog.csdn.net/nie7342/article/details/101292571),相对flask,Django是一个重量级框架,它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,我们甚至可以很方便的开发出自己的工具包。

MVC:

M: model层,负责 数据处理,包括对数据的增删改查等操作
V: view层,负责 界面显示
C: controller层,负责逻辑控制接收和处理请求,调用model和view
核心思想: 分层,解耦。MVC分离了 数据处理 和 界面显示 的代码,使得一方代码修改了不会影响到另外一方,提高程序的扩展性和可维护性。
Django是基于MVT的一种设计模式:
M: Model, 模型 与MVC中的M相同,负责对数据的处理
V: View, 视图 与MVC中的C类似,负责处理用户请求,调用M和T,响应请求
T: Template, 模板 与MVC中的V类似,负责如何显示数据(产生html界面)

Django项目搭建

一般我们建议在一个IDE中如果有不同的模块,如flask,爬虫,Django等,我们可以建虚拟环境,以避免各API或者安装环境的差异
1.新建虚拟环境

mkvirtualenv django_py3 -p python3

2.安装Django

pip install django==1.11.11

3.创建项目 django-admin startproject Django02
4.创建运用 python manage.py startapp users
从浏览器发起请求到做出响应的步骤:
浏览器发出http请求–>Django封装request–>url匹配对应视图函数–>Djanso返回并解析response对象–>浏览器渲染并展示内容

Django配置文件

在项目的 setting.py 配置文件中,进行项目相关配置的修改。

当前项目的根目录,Django会依此来定位工程内的相关文件,我们也可以使
用该参数来构造文件路径
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

开启debug = True,项目运行出错了,需要查看是哪里一行代码造成出错,再进行分析解决
修改本地语言与时区

 LANGUAGE_CODE = 'zh-hans'   # 语言设置为 中文
 TIME_ZONE = 'Asia/Shanghai'  # 时区设置为 亚洲/上海,注意没有北京

App应用配置:每次我们创建一个app的时候都需要在项目配置文件 settings.py 中的 INSTALLED_APPS 列表中进行绑定,这样才能运行。
静态文件配置
1.在项目根目录下创建 static_files 目录,并添加子目录和文件 imgs/avatar01.png
2.在 项目 settings.py 文件中进行配置

# 告知Django静态文件保存在哪个目录下
 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_files')]

URL配置:为了减轻项目的URL配置,我们可以在每个app底下建一个自己的url然后在总项目的URL中去include每个app的URL文件
例如:

项目下的 urls.py 文件
  urlpatterns = [

      # 包含users模块下的urls.py
      # 参数1: 匹配url的正则表达式
      # 参数2: 调用 inclucde 函数,包含users模块下的urls.py
      url(r'^users/', include('users.urls')),
  ]

#APP底下的 urls.py 文件 (此文件默认不存在,需要自己创建)
  urlpatterns = [
      # 配置url和视图函数,需要调用url函数,并传入参数
      # 参数1: 匹配url的正则表达式(需要用 ^ 和 $ 匹配开头和结尾)
      # 参数2: url匹配成功执行的视图函数
      url(r'^index$', views.index), 
  ]

请求与响应

客户端的传参方式:

1通过URL路径传递:例如http://127.0.0.1:8000/news/1/2 传递id和页码
2.通过查询字符串传递:http://127.0.0.1:8000/news?category=1&page=2
3.通过body传递:body传递的数据又可分为键值对,表单和非标单数据
键值对:category=1&page=2,非标单数据:如json或者xml {“category”: 1, “page”: 2}
4.通过http协议请求头传递

通过request获取请求参数

1.获取查询字符串: request.GET.get('参数名 '),如果是一键多值:request.GET.getlist(‘参数名’)

请求地址:http://127.0.0.1:8000/news2?category=1&page=2
def	index(request):
		category = request.GET.get('category ')
		page = request.GET.get('page')

		# ?category=1&page=2&a=3&a=4
   		# a = request.GET.getlist('a')  # 一键多值通过 getlist 获取
		 text = '<br/> category=%s, page=%s' % (category, page)
    	return HttpResponse(text)

2.获取请求体数据:请求体数据格式不固定,可以是json或者xml类型,应区别对待。可以发送请求体数据的请求方式有POST、PUT、PATCH、DELETE
获取表单数据 Form Data (键值对):request.POST.get(‘参数名’)
request.POST.get只能获取post方式提交的表单数据,如果是非post或者非表单类型的数据需要用request.body属性获取提交的数据后,再自己手动解析

def news3(request):
    category = request.POST.get('category')
    page = request.POST.get('page')

     # 一键多值通过从POST中用 getlist 获取
    # ?category=1&page=2&a=3&a=4
    # a = request.POST.getlist('a') 

    text = '获取body中的键值对:<br/> category=%s, page=%s' % (category, page)
    return HttpResponse(text)

非表单类型 Non-Form Data:如获取json, request.body–> json.loads转换成dict类型,然后按键取值

def news4(request):
    # 获取json字符串
    json_str = request.body
    # 解析json
    dict_data = json.loads(json_str)
    category = dict_data.get('category')
    page = dict_data.get('page')
    text = '获取body中的json数据: category=%s, page=%s' % (category, page)
    return HttpResponse(text)

Response

视图必须返回一个HTTPResponse对象或者HTTPResponse的子类对象而不能直接返回字符串,HTTPResponse常用的子类有:HttpResponseRedirect (重定向),JsonResponse (json)

  1. HttpResponse
    HTTPResponse(content = ‘内容’,content_type=响应体数据MIME类型, status=状态码)
    MIME类型包含以下三种:
    text/html html
    text/plain 普通文本
    application/json json

2.JsonResponse:返回json数据,同时设置响应头 Content-Type 为 application/json

def resp(request):
     return JsonResponse({'city': 'beijing', 'subject': 'python'})

但是当我们返回的data中包含中文的时候不可以直接返回,需要加上编码

 def resp(request):

     # 最终看到的效果是: {"name": "\u5f20\u4e09"}
     response = JsonResponse({"name":"张三"})
    response = JsonResponse(data, json_dumps_params={'ensure_ascii':False})
     return response

3.redirect重定向

 def resp(request):
      # 重定向到首页
      return redirect('/index')

4.reverse函数:根据映射名称找到正确的URL地址
url = reverse(‘users:index’)

cookie和session

cookie是由服务器生成的保存在客户端的数据,HTTP请求本来是无状态的,cookie可以追踪用户的访问记录,在响应请求时服务器会将cookie发送给浏览器,浏览器在请求服务器的时候会带上服务器返回的所有未过期的cookie
1.在服务端设置cookie
response.set_cookie(‘键’, ‘值’,max_age)
2.在客户端读取cookie
request.COOKIES[‘键’]
session也是服务器端生成的只不过session保存于服务器而非本地,且session多保存敏感信息,session依赖于cookie
1.设置session: request.session[‘键’]=值
2.读取session:request.session.get(‘键’, 默认值)
3.删除session: del request.session[‘键’]#当键不存在的时候会报错
request.session.flush() # 删除一条表记录
request.session.clear() # 清空字段中的session键值对数据
4.设置过期时间:request.session.set_expiry(value)#如果不设置默认为两周
5.配置将session保存到Redis当中

 pip install django-redis==4.8.0

然后修改settings,新增如下配置:

 # django项目的缓存配置
 CACHES = {
     "default": {
         "BACKEND": "django_redis.cache.RedisCache",
         "LOCATION": "redis://127.0.0.1:6379/1",
         "OPTIONS": {
             "CLIENT_CLASS": "django_redis.client.DefaultClient",
                 "PASSWORD": ""
         }
     }
 }

 # session数据缓存到Redis中
 SESSION_ENGINE = "django.contrib.sessions.backends.cache"
 SESSION_CACHE_ALIAS = "default"

类视图

上代码:

 from django.views.generic import View
 class PostView(View):
     def get(self, request):
         """get请求: 显示发帖界面"""
         return render(request, 'post2.html')
     def post(self, request):
         """post请求: 执行发帖操作"""
         # 代码简略
         return HttpResponse('执行发帖操作')
urlpatterns = [
     ...
     # 类视图注册
     url(r'^post2$', views.PostView.as_view()),
 ]

如果我们想用一个视图实现get,post两个请求,推荐使用类视图,虽然函数视图也可以实现但需要我们手动判断请求方式。然后普通视图函数的URL直接是views.视图函数名,但类视图函数得用as_view来转换。对于函数视图代码可读性和复用性更好。
类视图装饰器:
1.直接在URL中进行装饰

urlpatterns = [
    ...
    # 发帖功能
    url(r'^post2$', check_ip(views.PostView.as_view())) #check_ip为我们装饰器的名字
]

2.在类方法中进行装饰:利用method_decorator(装饰器名)

    @method_decorator(check_ip)
    def get(self, request):
        """get请求:显示发帖界面"""
        return render(request, 'post2.html')

3.类视图多继承 & Mixin扩展类
学过c++的其实很容易理解,比如我们新建class A拥有遍历方法,新建class B拥有增加方法,然后我们有class C同时继承了A和B类,然后C类有自己的删除方法,于是C类就有了遍历,新建和删除这三个方法。类视图的多继承便于代码的复用和扩展。

class ListModelMixin(object):
    """
    list扩展类
    """
    def list(self, request, *args, **kwargs):
        print('查询多条数据')
        ...
class CreateModelMixin(object):
    """
    create扩展类
    """
    def create(self, request, *args, **kwargs):
        print('新增一条数据')
        ...
class DepartmentView(CreateModelMixin, ListModelMixin, View):
    """
    同时继承两个扩展类,复用list和create方法
    """
    def get(self, request):
        self.list(request)
        ...
    def post(self, request):
        self.create(request)
        ...
class EmployeeView(CreateModelMixin, View):
    """
    继承CreateModelMixin扩展类,复用create方法
    """
    def post(self, request):
        self.create(request)
        ...

中间件

什么叫中间件?中间件的作用和装饰器很类似,用于在视图函数调用之前或之后执行额外操作,在全局上修改Django的输入或输出,而装饰器只能对被装饰的单个函数起作用。

1.定义中间件类: 通过继承Django的MiddlewareMixin扩展类实现:
init(self, get_response=None)服务器启动,初始化中间件类时被调用,只执行一次 process_request(self, request):在视图执行之前调用,注意:该方法可以返回None或者response对象,如果返回response对象,则视图函数就不会再执行了
process_response(self, request, response): 在视图执行之后调用,必须返回 response 对象
2.在setting.py文件中的MIDDLEWARE中注册
新建一个middleware.py然后写一个简单的中间件

 class MyMiddleware(MiddlewareMixin):
     def __init__(self, get_response=None):
         super().__init__(get_response)
         print('init')
     def process_request(self, request):
         print('before 视图')
         # 注意:可以返回None或者response对象,如果返回response对象,则视图函数就不会再执行了
     def process_response(self, request, response):
         print('after 视图')
         return response

代码写完之后在settings中注册我们的中间件,这样才能被启用

 MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     ...

     'middlewares.MyMiddleware',  # 注册中间件
 ]

这样就OK了,我们随便运行哪个视图函数都会起到我们的中间件。
那么如果我们定义了多个中间件的话执行顺序是这样的:

对于视图之前执行的 process_request 方法,先 注册的中间件先执行
对于视图之后执行的 process_response 方法,后 注册的中间件先执行

模板

模板这里主要补充一下Django渲染模板的方法,Django依旧使用模板语言Jinjia2,参考前面的flask教程(https://blog.csdn.net/nie7342/article/details/101292571)
1.配置模板文件
在项目根目录下创建模板目录,比如叫 templates,后续开发模板文件会放在此目录下
2.在项目的配置文件settings.py文件中,进行模板目录的配置,如下:
在这里插入图片描述
2.模板渲染
Django支持两张类型的模板渲染

#利用render直接渲染render(请求对象,模块路径,字典数据)
def index(request):
    context = {'name': 'django' }
    # 参数1:请求对象
    # 参数2:模块路径
    # 参数3:字典数据
    return render(request, 'index.html', context)

#利用template.render()进行渲染,在渲染之前我们需要通过 loader.get_template来获取template对象
def index(request):
    # 获取模板对象
    template = loader.get_template('index.html')  
    # 渲染得到字符串
    html_str = template.render(context)
    # 响应请求
    return HttpResponse(html_str)

还有关于Django数据库以及admin站点的总结会抽时间奉上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值