Python调C 法力无边

目前对于Python web来说,主流框架是Djangoflask.有同学会问,什么框架呢?打一个比方,就是这个包已经帮你做好整体框架(类似于骨架的概念),而你就是在里面缝缝补补,增加细节,一般也都是在settings.py上进行修改配置
当然了,Python 毕竟是脚本语言性能上面远达不到我们需要的要求,但是其用框架搭建网站是十分快捷的。对于学生来说或者一些小项目可以考虑使用Python的上述两种框架
当然,对于前端的一些知识可以设计开发中慢慢增长,但是基础概念需要掌握的,不过不用在这里耗太久。
而本次的Django框架也仅仅从模版模型表单视图基本内容为主,后续再持续深入,特别是ORM数据库实例等,倘若还有时间再进行简单管理系统进行开发

本次环境 Python 3.10 Pycharm 2022 Django 3.2

简介创建

django本身基于mvc模型,即model view controller 设计模式。是快速开发网站、设计、部署网站的最佳组合
model:编写程序应有的功能负责业务对象数据库映射
view:图形界面,负责与用户交互
controller:负责转发请求,对请求进行处理

使用pip 安装django:

pip3 install Django -i https://pypi.tuna.tsinghua.edu.cn/simple

或者直接在pycharm下载对应模块

使用命令行创建项目


django-admin startproject helloworld
cd helloworld/

或者使用pycharm进行创建(个人推荐使用命令行
在这里插入图片描述
helloworld文件包,可以看到如上的目录结构
HelloWorld: 项目的容器
manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互
HelloWorld/init.py: 一个文件,告诉 Python目录一个 Python 包。
HelloWorld/asgi.py: 一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
HelloWorld/settings.py: 该 Django 项目的设置/配置
HelloWorld/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动网站目录“。
HelloWorld/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。

如何运行了呢?使用如下命令启动服务器,

python3 manage.py runserver 127.0.0.1:8000

进入如下界面,就说明已经配置成功了。(说真的,这个比配置tomcatspringboot简单多了,也不愧是快速开发的首选框架
请添加图片描述
或者也可以pycharm配置相应的设置方便快速
请添加图片描述
由于创建的helloworld没有views.py文件,所以需要在此目录下创建views.py,并写相应的请求这里helloworld为例

from django.http import  HttpResponse

def hello(request):
    return HttpResponse("Hello world!");

同时需要urls.py绑定views.hello,注意views.hello不要加括号

from django.contrib import admin
from django.urls import path
from django.conf.urls import  url
from . import  views

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^$',views.hello),
    # path('hello/', views.hello),
]

Django path()可以接收4个参数,分别是两个必选参数routeview 和两个可选参数kwargsname
route: 字符串表示 URL 规则,与之匹配的 URL 会执行对应第二个参数 view。
view: 用于执行正则表达式匹配的 URL 请求
kwargs: 视图使用的字典类型参数
name: 用来反向获取 URL。

Django模版

上述内容中将数据视图混合一起了,不符合MVC思想。而模版是一个文本用于分离文档的表现形式和内容
在helloworld目录下创建Templates目录并建立runoob.html文件

<h1>{{ hello world }}</h1>

接下来settings.py导入位置 ‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)],在这里插入图片描述
修改 views.py,增加一个新的对象用于模板提交数据
其中render用来传递conText填充模版

from django.shortcuts import  render

def runoob(request):
    context = {}
    context['hello'] = 'hello world'
    return render(request,'runoob.html',context)

修改urls.py:

from django.urls import path
 
from . import views
 
urlpatterns = [
    path('runoob/', views.runoob),
]

再次访问 http://127.0.0.1:8000/runoob即可访问了。

Django模版标签

变量
模版语法

view: {"html-name" : "views-name"}
HTML: { {变量名} }

return render(request,"runoob.html",{"name":views_name})


# runoob.html:
<p>{ {name} } </p>

列表

html中,可以用 . 索引下标取出对应元素

# views.py
def runoob(request):
	view_list = ["123","456"]
	return render(request,"runoob.html",{"views_list":views_list})

# 列表
<p> {{view_list}}</p>
<p> {{view_list.0}} </p>

过滤器

过滤器有lower. upper. truncatewords. addslashes. date length

此处在runoob.html进行过滤
{{变量名过滤器:可选参数 }} 
{{name|lower}}   # 模版过滤可以变量显示修改它,过滤器使用管道字符
{{bio|truncatewords:"30"}} # 将显示bio的前三十个词

过滤器的目的就是过滤使得获取到相应的字符内容
下面讲一个safe:

{{ views_str | safe}}
标记安全需要转义,保障绝对安全才能用safe

def runoob(request):
	views_str = "<a href='https://www.runoob.com/'>点击跳转</a>"
	return render(request,"runoob.html",{"views_str":views_str})


# runoob.html:
{{ views_str |safe }}

标签

if / else 标签:

{ % if condition %}
	... display
{% endif %}

或者
{ % if condition1 %}
    ... display1
 {% elif condition2 %}
    ... display2
 {% else %}
{ % endif % }

{ % if  athlist and coachlist %}
{% endif %}

for标签:
{ % for % }

<ul>
	{ % for athlete in athlete_list   (reversed)%}
	     <li> {{ athlete.name }} </li>
	{% endfor %}
</ul>

遍历字典

# views.py:
def runoob(request):
	views_dict={"name":"cai","age":18}
	return render(request,"runoob.html",{"views_dict":views_dict})

# runoob.html:
{ % for i ,j in views_dict.items %}
{{i}} --- {{j}}
{% endfor% }

ifequal/ifnotequal标签:
{ % ifequal %}比较两个值,当他们相等的时候,显示内容:

{% ifequal user currentuser %}
   <h1> welcome </h1>
{% else % }
	<h1> No </h1>
{% endifequal %}

注释

{ # 这是一个注释 #}

include 标签 允许在模版包含其他的模版内容

{ % include "nav.html" % }

csrf_token
用于form表单中,作用是跨站请求伪造保护。如果不用的话,再次跳转会抱403权限错误

自定义标签和过滤

应用目录下,建一个templatetags (和templates同级
在该目录下建一个任意Py文件

# my_tag.py:
from django import template

register = template.Library() #register名字固定不可改变

其中在settings.py templates添加libraries配置:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [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',
            ],
            "libraries":{                          # 添加这边三行配置
                'my_tags':'templatetags.my_tags'   # 添加这边三行配置        
            }                                      # 添加这边三行配置
        },
    },
]

my_tag.py中建立过滤器与自定义标签
注意 {% 没有空格!!!

@register.filter
def my_filter(v1, v2):
    return v1 * v2

@register.simple_tag
def my_tag1(v1, v2, v3):
    return v1 * v2 * v3

# 在html文件头部导入py文件
{% load my_tag %}

{{ 11|my_filter:22 }}

配置静态文件

根目录下创建statics目录,在settings最下方配置:

STATIC_URL = '/static/' # 别名 
STATICFILES_DIRS = [ 
    os.path.join(BASE_DIR, "statics"), 
]

statics目录下创建css目录 js目录 images目录 plugins目录 分别放css文件 js文件,图片插件
bootstrap框架放入插件目录 plugins
html文件的head标签中引入bootstrap,注意引用路径配置文件是别名static

<link rel="stylesheet". href="/static/plugins/bootstrap-3.3.7/dist/css/bootstrap.css">
# html:

{% load static %}
{{name}} <img src="{% static 'images/runoob-logo.png'%}" alt="runoob-logo">

模版继承

继承实现复用,减少冗余内容
父模版 blockendblock 父模版中的预留区域

{% block name %}
预留给子模版的区域可以设置默认内容
{% endblock name %}

子模版 使用extends 继承父模版

{ % extends "父模版路径" %}

templates目录下添加 base.html文件:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>菜鸟教程 Django 测试</p>
    {% block mainbody %}
       <p>original</p>
    {% endblock %}
</body>
</html>

使runoob.html对其继承

{%extends "base.html" %}
 
{% block mainbody %}
<p>继承base.html 文件</p>
{% endblock %}

Django 模型

Django对数据库提供了很好的支持,提供了统一调用API,先安装pymysql模块,本次使用的数据库mysql,同时使用的是阿里服务主机ip.

ORM

ORM:对象关系映射,用于实现数据之间的转换。在业务逻辑层和数据库之间充当了桥梁的作用,通过使用描述对象数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。
好处:提高开发效率,不同数据库可以切换,但是需要转换sql语句时,执行效率低。
其中 models数据表 对象实例一条记录 属性字段

*数据库配置

settings.py文件中找到databases配置项,将信息修改为:

DATABASES = { 
    'default': 
    { 
        'ENGINE': 'django.db.backends.mysql',    # 数据库引擎
        'NAME': 'runoob', # 数据名称
        'HOST': '127.0.0.1', # 数据地址本机 ip 地址 127.0.0.1 ;有服务器就设置自己的服务器
        # 服务器记得关闭防火墙,嫌麻烦端口全部打开
        'PORT': 3306, # 端口 
        'USER': 'root',  # 数据用户名
        'PASSWORD': '123456', # 数据密码
    }  
}

settings中的__init__.py中引入模块并进行配置:

import pymysql
pymysql.install_as_MySQLdb()

定义模型

使用命令创建app

django-admin startapp TestModel

在TestModel/models.py文件夹下附以下代码
类名代表数据表名继承Model,字段(name),数据类型(CharField) maxlength参数限定长度

from django.db import models
 
class Test(models.Model):
    name = models.CharField(max_length=20)

同时子啊settings.py中找到INSTALLED_APPS这一项,如下

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'TestModel',               # 添加此项
)

命令行运行,当然也可以使用数据工具,创建表TestModel_test

use runoob
create  table TestModel_test (
	name varchar(20)
)
$ python3 manage.py migrate   # 创建表结构

$ python3 manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
$ python3 manage.py migrate TestModel   # 创建表结构

*数据库操作

在django框架中,统一都是继承Models,为了兼顾众多数据库不同的语言特性,特此开发出的功能。
下面都是一些常规的增删改查操作,不用特意去记忆,平时敲敲也就记住了,当然重点是前面步骤没有出现差错。
回到helloworld/urls.py

from django.urls import path

from . import views, testdb

urlpatterns = [
    path('runoob/', views.runoob),
    path('testdb/', testdb.testdb),
]

/helloworld/testdb 增加数据

from django.http import HttpResponse

from TestModel.models import Test


# 添加数据 (由于我这里models.py中只设置了name一列)
def testdb(request):
    test1 = Test(name='runoob')
    test1.save()
    return HttpResponse("<p>数据添加成功!</p>")

运行程序,可以看到网页显示数据添加成功,同时可以回到数据工具台,使用select语句 ,看是否成功添加。

获取数据查找,注意获取时候需要循环循环for var in list 读取想要的格式,否则会报can only concatenate str (not “QuerySet”) to str错误

# testdb.py
from django.http import HttpResponse

from TestModel.models import Test


# 数据库操作
def testdb(request):
    # 初始化
    response = ""
    response1 = ""

    # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
    list = Test.objects.all()

    # filter相当于SQL中的WHERE,可设置条件过滤结果
    response2 = Test.objects.filter(name="jacin")

    # 获取单个对象
    response3 = Test.objects.get(id=1)

    # 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;
    Test.objects.order_by('name')[0:2]

    # 数据排序
    Test.objects.order_by("id")

    # 上面的方法可以连锁使用
    Test.objects.filter(name="runoob").order_by("id")

    # 输出所有数据
    for var in list:
        response1 += var.name + " "
    # response = response1
    for var in response2:
        response += var.name + " "
    return HttpResponse("<p>" + response + "</p>")

更新数据(改),使用save() 或者 update()

# -*- coding: utf-8 -*-

# -*- coding: utf-8 -*-

from django.http import HttpResponse

from TestModel.models import Test


# 数据库操作
def testdb(request):
    # 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
    test1 = Test.objects.get(id=1)
    test1.name = 'Google'
    test1.save()

    # 另外一种方式
    # Test.objects.filter(id=1).update(name='Google')

    # 修改所有的列
    # Test.objects.all().update(name='Google')
    re=Test.objects.filter(id=1)
    str=""
    for var in re:
        str += var.name
    return HttpResponse("<p>"+str+"  修改成功</p>")

删除数据

from django.http import HttpResponse

from TestModel.models import Test


# 数据库操作
def testdb(request):
    # 删除id=1的数据
    test1 = Test.objects.get(id=1)
    test1.delete()

    # 另外一种方式
    # Test.objects.filter(id=1).delete()

    # 删除所有数据
    # Test.objects.all().delete()

    return HttpResponse("<p>删除成功</p>")

Django表单

html表单网站交互性的经典方式。可以查看此处链接点击此处
http协议请求-回复 方式工作的,发送请求时候可以附加数据,服务器通过解析请求,可以获得传来的数据,并根据url来提供特定的服务。

GET方法

helloworld/helloworld/search.py

from django.http import HttpResponse
from django.shortcuts import render
# 表单
def search_form(request):
    return render(request, 'search_form.html')
 
# 接收请求数据
def search(request):  
    request.encoding='utf-8'
    if 'q' in request.GET and request.GET['q']:
        message = '你搜索的内容为: ' + request.GET['q']
    else:
        message = '你提交了空表单'
    return HttpResponse(message)

/helloworld/templates/search_form.html
注意action 属性提交位置这里search下面url跳转地址

 <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="搜索">
 </form>

/urls.py

from django.conf.urls import url
from . import views,testdb,search
 
urlpatterns = [
    url(r'^hello/$', views.runoob),
    url(r'^testdb/$', testdb.testdb),
    url(r'^search-form/$', search.search_form),
    url(r'^search/$', search.search),
]

POST方法

get:视图显示和请求处理分成两个函数处理
其实提交数据更常使用post,使用url+处理函数
/helloworld/templates/post.html:
csrf_token:django提供的防止伪装提交的功能,post方法提交表格,必须有此标签

<form action="/search-post/" method="post">
        {% csrf_token %}
        <input type="text" name="q">
        <input type="submit" value="搜索">
</form>

<p>{{ rlt }}</p>  <!--预留位置,为表格处理结果预留-->

/helloworld/helloworld/search2.py

# -*- coding: utf-8 -*-

from django.shortcuts import render
from django.views.decorators import csrf


# 接收POST请求数据
def search_post(request):
    ctx = {}
    if request.POST:
        ctx['rlt'] = request.POST['q']
    return render(request, "post.html", ctx)

强调一下,需要加上search-post后面的斜杠,否则读取不到

# urls.py +
 path('search-post/',search2.search_post),

get和post的区别

get: 提交的数据小于1024字节,表单提交时表单数据将在地址栏显示
post:传递数量不限制提交数据会隐藏安全性能较高,对信息也做了隐藏

Request 对象

每个视图第一个参数是一个HttpRequest对象

from django.http import HttpResponse

def runoob(request):
	return HttpResponse("hello world")

path : 请求页面的全路径,不包括域名
method : repuest.method == ‘GET’ ‘POST’
cookies: 包含所有cookies的标准python字典对象
meta包含所有http头部信息字典
session:唯一读写属性

Django视图

视图函数,接受web请求并返回web响应响应可以是html页面等。
视图有两个重要的对象,分别是请求对象 request 与 HttpResponse
请求对象 (HttpRequest对象)

GET

数据类型是QuerDict,类似于字典的对象,取值格式: 对象.方法,get()

def runoob(request):
	name = request.GET.get("name")
	return HttpResponse('name:{}'.format(name))

POST

数据类型和GET一致

def runoob(request):
	name = request.POST.get("name")
	return HttpResponse('name:{}'.format(name))

path

获取URL的路径数据类型字符串

def runoob(request):
	name=request.path
	print(name)
	return HttpResponse("name")

method

获取当前请求的方式,数据类型字符串结果大写

def runoob(request):
	name = request.method
	print(name)
	return HttpResponse("name")

Django路由

路由就是根据用户请求的URL来判断对应处理程序,并返回处理结果,即URL与Django的视图建立映射关系
path:普通路径,不需要自己手动添加正则首位限制符号底层添加
re_path: 正则路径 ,需要手动添加正则首位限制符号

关于正则表达式,我将单独出一期笔记

无名分组

正则路径的无名分组,按位置传参,一一对
views除了request ,其他行参数量与urls中的分组数量一致
下面的路径就是index/year(具体的日期

# views.py
from django.shortcuts import HttpResponse

def index(request,year):
	print(year)
	return HttpResponse("name")
# urls.py
urlpatterns = [
	path('admin/',admin.site.urls),
	re_path("^index/[0-9]{4}/$",view.index),
]

有名分组

故名思义,有名分组按照关键字传参,与顺序无关

(?P<组名> 正则表达式)
# views.py
from django.shortcuts import HttpResponse
def index(request, year, month): 
    print(year,month) # 一个形参代表路径中一个分组的内容,按关键字对应匹配 
    return HttpResponse('name')

# urls.py

re_path("^index/(?P[0-9]{4}/(?P[0-9]{2}/$",views.index)

路由分发(include)

问题:django 项目多个app目录使用一个urls会造成混淆,后期维护也不方便
解决:使用路由转发,每个app目录都有urls

from app01 import views
# urls.py
	path("app01/",include("app01.urls"))

反向解析

随着功能的增加,路由层的url发生变化,需要修改对应的视图层和模版层的url,比较麻烦
可以利用反向解析,当url发生变化可以反向解析,一般用在模版中的超链接及视图中的重定向

普通连接

# 
path("login1/",view.login,name="login")

# 在views.py ,从urls 引入reverse
return redirect(reverse("login"))

#templates/ .html
<form action="{% url 'login' %}" method="post">

正则路径(无名分组

# urls.py
re_path(r"^login/([0-9]{2})/$",views.login,name="login")

# views.py
# 引入reverse 利用reverse("路由别名“,args=(符合正则匹配参数,))
return redirect(reverse("login",args=(10,)))

#/templates/ .html
<form action={% url 'login' 10 %}" method="post">

正则路径(有名分组)

# urls.py
re_path(r"^login/(?<year>[0-9]{4}/$",views.login,name="login")

# views.py
return redirect(reverse("login",kwargs={"year":3333}))

# html
<form action="{% url 'login' year=3333 %}" method="post">

命名空间

故名思义,和其他的编程语言类似。是标识空间定义
普通路径

include(("app名称:urls","app名称"))

原文地址:https://blog.csdn.net/QAZJOU/article/details/125989130

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_23192.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注