Python Web框架Django从入门到放弃

在这里插入图片描述
在这里插入图片描述
Python除了学习基础知识之外,最常用的三大块就是数据挖掘分析,人工智能,Web开发,今天就介绍下Python全栈工程师必备的知识点之一Web开发

简介

Web整体框架

Web框架: 别人已经设定好的一个Web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要的样子。
其它基于Python的Web框架,如Tornado、Flask、Django都是在这个范围内进行增删裁剪的。例如Tornado用的是自己的异步非阻塞通信协议,Flask则只提供了最精简和基本的框架,Django直接使用WSGI通信协议,并实现了大部分Web应用相关的功能。

图1 Web框架
图1

Web服务器架构(uWSGI)

什么是WSGI?(上图黄色部分)
这里画的黄色WSGI是统称而已,其实本身是有几个部分组合而成。

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。

  1. WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。
  2. uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器(Nginx)的数据通信。
  3. uWSGI是实现了uwsgiWSGI两种协议的Web服务器。
  4. uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

图2 Web服务器架构
在这里插入图片描述
Nginx
通俗易懂的理解下Nginx
1.静态HTTP服务器
首先它是一个http服务器,可以将服务器上的静态文件(html,图片)通过http协议展现给客户端

2.反向代理和负载均衡
这两个特性都是相辅相成的,想象下,如果没有ng,客户端可以直接通过http协议访问某网站的应用服务器。如果加上ng,就类似ng成为了一个代理服务器,而且是反向代理服务器。(正向代理就是我们OC中写的代理,反向代理可以理解为给10086打电话)。当网站访问量大,一台服务器不够用,就会把应用部署到多台服务器上,大量用户分配给多台机器,挂一台也不影响其他。

3.反向代理和虚拟主机
有的网站访问量大就需要负载均衡。但是小公司前期没很多访问量,一台服务器也够了,会将多个网站部署到同一台服务器上。例如aaa.com和bbb.com两个网站部署在同一台服务器,两个域名解析到同一个IP,访问各自的应用网站,就像两个服务器一样,这就是所谓的虚拟主机

个人通俗的来理解下:在开始入门之前先了解下,咱们一般都是用Nginx和uWSGI进行部署我们的Django应用。首先这里客户端请求,进入Nginx,如果是静态资源,直接读取,其他转发进入uWSGIweb服务容器,首先和左侧和Nginx交互的时候实现了uwsgi协议,右侧和Django应用交互的时候实现了WSGI协议,这就是三个名词的基本理解了。

Python服务器类比Java

  • 独立WSGI server(实现了Http服务器功能) + Python Web应用程序
    • 例如:Gunicorn,uWSGI + Django,Flask
  • 独立Servlet引擎(Java应用服务器)(实现了Http服务器功能) + Java Web应用程序
    • 例如:Jetty,Tomcat + SpringMVC,Struts2

Python和Java服务器共同点

  • WSGI server(例如Gunicorn和uWSGI)

    • WSGI server服务器内部都有组建来实现Socket连接的创建和管理。
    • WSGI server服务器都实现了Http服务器功能,能接受Http请求,并且通过Python Web应用程序处理之后返回动态Web内容。
  • Java应用服务器(Jetty和Tomcat)

    • Java应用服务器内部都有Connector组件来实现Socket连接的创建和管理。
    • Java应用服务器都实现了Http服务器功能,能接受Http请求,并且通过Java Web应用程序处理之后返回动态Web内容。

Django 整体架构

图3 Django MTV模型组织
在这里插入图片描述
当一个通过上面的NgnixuWSGI转发后最后请求Django站点的时候,下面是Django系统决定执行哪个Python代码的算法:

  1. 我们创建的项目startproject xxx,有个根的root conf,一般会从ROOT_URLCONF该字段读取,但是如果有个HttpResponse对象有urlconf属性(set by middleware),这个值就会被替换掉(Django中间件全过程解析
  2. Django加载匹配模块是根据urlpatterns参数的,该参数是django.urls.path() 或者 django.url.re_path()组成的列表
  3. Django依次匹配URL,匹配到第一个就停下来
  4. 一旦匹配到,会根据conf模块下是继续分发还是直接调用执行函数
  5. 如果匹配失败,抛出异常,调用内置的错误view模块显示
    6.成功后执行View里面的函数,分别能绑定model和template,model对应ORM操作数据库,template用于接收model数据,渲染结果。
    7.处理完后原理返回到客户端。

图1是整体架构,图2是对应图1WSGI部分详细结构图,图3是Django的MTV整体架构图。
以下就是Python的Web开发技术栈。如果一个人开发,前端这些技术必须掌握,Web服务器搞懂NginxuWSGI,公共组件按需取舍,全部用pip进行安装,类似OC的cocoapods,Django自带了几种ORM数据库后端,本地开发SQLIte即可,但是如果你要部署到服务器,MySQL服务器就必须掌握。
在这里插入图片描述

开发入门

1.安装虚拟环境

which python3
cd Desktop
mkdir Hello
virtualenv -p /usr/local/bin/python3 venv
source venv/bin/activate
# 或者 . venv/bin/activate
# deactive 关闭虚拟环境
pip install django==2.2.4

2.创建项目

django-admin startproject mysite
mkdir templates

在这里插入图片描述
这里我们创建了一个主工程文件mysite,templates如果你是用IDE启动的话默认安利给你的文件夹,也就是MVT模型中的T。manager.py就是项目管理脚本。

python manager runserver可以看到启动了DJango服务器。

3.创建app 配置Pycharm参数

python manager.py startapp login

这里我们要编写稍微完整一点的Demo,用Pycharm来接管整个工程,如果你创建项目直接用Pycharm也行,但是有些你从Github下载下来的项目,你用Pycharm打开加工的话,一样需要了解一点基本的配置,不然连一点提示都没有,下面就是完整的配置。

1.模板文件提示,Pythcharm----Preference-----Language&Framework-----Python Template Languages设置成Django,这样模板文件就有了模板提示

2.代码提示,资源跳转 Pythcharm----Preference-----Language&Framework-----Django------设置参数
在这里插入图片描述

3.templates文件设置,右击----Make Directory as-----Template Folder 文件夹变成紫色,同时需要在Settings.py中设置查找路径
在这里插入图片描述
4.venv文件设置,右击----Make Directory as-----Exclusion 变成橙色

5.根目录设置,右击----Make Directory as-----SourcesRoot 变成蓝色

编写路由

此时我们的项目有一个主工程mysite,一个子工程Applogin,首先打开mysite/urls.py文件处理总路由入口

from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^', include('login.urls', namespace='login'))
]

这里我们主工程一般不做处理,直接转发到对应的模块,比如这里转发到login模块的urls.py去匹配,但是我们需要在settings.py中注册login

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'login'
]

然后在login模块中创建一个urls.py进行匹配

from django.urls import re_path
from . import views

app_name = 'login'

urlpatterns = [
    re_path(r'^index$', views.index, name='mysite_index'),
]

编写视图

from django.http import HttpResponse

def index(request):
    return HttpResponse('Hello world')

返回HTML模板

上面只是简单介绍了从路由到View视图处理完的一套流程,下面接入HTML模板进行演示

首先在根目录新建一个文件夹static,创建一个index.css出来,然后再templates下面新建一个index.html
这两个文件都需要在settings.py中设置查找路径

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',
            ],
        },
    },
]

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

修改视图返回值,用模板进行渲染

from django.shortcuts import render
def index(request):
    context = {}
    context['content'] = 'Hello world'
    return render(request, 'index.html',context)

模板页面加载静态资源以及读取数据的方式

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'index.css' %}">
</head>
<body>
<h1>{{ content }}</h1>

</body>
</html>

启动服务

python manage.py runserver 输入127.0.0.1:8000/index就能看到我们的Hello World

完整Demo

描述一个用表单提交数据,然后展示出来的框架Demo

设计页面

# 表单页面
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'index.css' %}">
</head>
<body>
<h1>登录</h1>
<form action="{% url 'login:mysite_submit' %}" method="post">
	{% csrf_token %}
    用户:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>
# 结果页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    {% for user in lists %}
        姓名:{{ user.username }}
        密码:{{ user.password }}
        <br>
    {% endfor %}
</ul>
</body>
</html>

模型设计

from django.db import models
class UserInfo(models.Model):
    username = models.CharField(max_length=20)
    password = models.CharField(max_length=20)

模型设计好之后,我们需要生成迁移文件以及迁移到数据库建表
python manager.py makemigrationspython manager.py migrate

编写路由

# 加多一条提交的路由
from django.urls import re_path
from . import views

app_name = 'login'

urlpatterns = [
    re_path(r'^$', views.index, name='mysite_index'),
    re_path(r'^submit$', views.submit, name='mysite_submit')
    # re_path(r'^detail/(\d+)/$', views.blog_details, name='blog_details'),
]

编写View

# 处理逻辑
from django.shortcuts import render
from django.http import HttpResponse
from .models import UserInfo

def index(request):
    context = {}
    context['content'] = 'Hello world'
    return render(request, 'index.html',context)


def submit(request):

    if request.POST:
        username =  request.POST.get('username')
        password =  request.POST.get('password')
        user, created =  UserInfo.objects.get_or_create(username=username, password=password)
        if created:
            user.save()
    lists =  UserInfo.objects.all()
    return render(request, 'result.html', context={'lists': lists })

这里写逻辑的时候我们可以进到shell模式进行测试

python manage.py shell
>>> from login.models import UserInfo
>>> x = UserInfo.objects.all()
>>> x
<QuerySet []>
>>> str(x.query) # 查看对应的sql
'SELECT "login_userinfo"."id", "login_userinfo"."username", "login_userinfo"."password" FROM "login_userinfo"'

编写Admin显示的模型

from django.contrib import admin
from .models import UserInfo

@admin.register(UserInfo)
class UserInfoAdmin(admin.ModelAdmin):
    list_display = ['pk','username','password']
    

创建超级管理员

python manage.py createsuperuser

随后就可以通过127.0.0.1:8000/admin进入后台管理页面,其中能看到我们之前处理admin.py得到的条目,可以添加或者删除数据,博客后台就这么搞定了。

启动服务

python manager.py runserver

疑惑

针对这个简单的Demo,也罗列了用到的一些知识点,下面已经单独写了博客分析了

模板标签

可以看到很多类似的 {% csrf_token %}{% static 'index.css' %}的东西,这个其实就是模板标签,简单理解就是左边那个是函数,有没有右侧代表函数是否带参数,很显然,static就带参数。我们来模拟一个用途
首先保证你的App被注册进入了,然后再models.py的同级目录下创建一个Python包
在这里插入图片描述
上面的最基本的自定义Tag,首先在模块里面必须包含一个register的模块级变量,才可以通过装饰器注册tag标签,使用如下

{% load login_tags %}
......
<h1>登录{% get_comment_count '1000' %}</h1>
......

CSRF Token作用

CSRF

装饰器

装饰器和偏函数

内置模块App

六大模块之ContentType App

内置中间件 (MIDDLEWARE)

中间件

部署前准备 (数据库迁移)

SQLIte迁移成Mysql

部署前准备 (静态资源搜集)

静态资源开发配置和部署搜集

总结:上面介绍了Django Web开发最基本的框架,开发阶段静态资源不需要单独处理,只需要指定路径即可,部署的时候我们会通过脚本把静态资源搜集到一个目录下,配置给到Nginx进行管理。开发阶段的数据库可以用SQLIte进行,不需要单独的其他配置,等到部署之前,需要按上面的教程迁移到Mysql,其中涉及到一些坑已经有详细介绍,跟着做就好了,特别注意Mysql的字符编码集和校对规则就好了,不然数据不兼容是最难受的。本地部署前准备后就需要买个服务器进行部署了,时间不多,下次在详述如何用Nginx和uWSGI部署到Center OS服务器。

以下是空余时间陆陆续续写的博客框架,放在Github了,有兴趣的可以研究下传送门

在这里插入图片描述
参考文档:
Nginx

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值