首页 > 编程语言 >python-Django基础学习笔记

python-Django基础学习笔记

时间:2024-03-08 14:00:29浏览次数:17  
标签:python py request 笔记 Django models html test path

(由于笔记来自本地的Typora,图片未能上传,文章内容并不完整)

路由器配置

  1. 初始Django - 创建/结构/配置settings
  2. URL定义/视图函数
  3. 路由配置 path、re_path
python -m venv "名字"
#下载Django环境
pip install django == 2.2.2 -i https://pypi.douban.com/simple 
#激活虚拟环境
D:\djangoProject\dj_base\Scripts\activate

# http://127.0.0.1:8000/page/1
path('page/1',views.page1_view)
#views.py 中的添加内容
def page1_view(request):
    html = "这是编号为1的编号"
    return HttpResponse(html)

Path转换器

image-20221115002343451

# http://127.0.0.1:8000/page/3-100
path('page/<int:pg>',views.pagen_view)

##此时在views.py中需要如此写
def pagen_view(request,pg):
    html="这是编号为%s的网页"%(pg)
    return HttpResponse(html)

path的执行顺序是由上而下直至找到结束,并不会在找到的情况下执行

练习:小计算器

#urls.py
# http://127.0.0.1:8000/整数/操作符/整数
path('<int:n>/<str:op>/<int:m>',views.cal_view)
#views.py
def cal_view(request,n,op,m):
    if op not in ['add','sub','mul']:
        return HttpResponse("Your op is wrong")
    result = 0
    if op == 'add':
        result = n+m
    elif op == 'sub':
        result = n-m
    elif op == 'mul':
        result = n*m
    return HttpResponse('结果为:%s'%(result))

若只能做两位数的计算:(上面的path转换器就不够用了)

  • re_path()

​ 在URL的匹配过程中可以使用正则表达式进行精确匹配

语句:

  • re_path(reg,view,name = xxx)
  • 正则表达式命名分组模式(?P<name>pattern);匹配提取参数后用关键字传参方式传递给视图函数
#正则表达式(\d 表整数,\w+ 表多个字符)
#urls.py
# http://127.0.0.1:8000/整数2/操作符/整数2
re_path(r'^(?P<x>\d{1,2})/(?P<op>\w+})/(?P<y>\d{1,2})$')
#views.py
def cal2_view(request,x,op,y):
    html = 'x:%s op:%s y:%s'%(x,op,y)
    return HttpResponse(html)

练习 :http://127.0.0.1:8000/birthday/2015/12/11

#urls.py
#http://127.0.0.1:8000/birthday/年/月/日
re_path(r'^birthday/(?P<x>\d{4})/(?P<y>\d{1,2})/(?P<z>\d{1,2})$',views.birthday_view)
#http://127.0.0.1:8000/birthday/年/月/日
re_path(r'^birthday/(?P<x>\d{1,2})/(?P<y>\d{1,2})/(?P<z>\d{4})$',views.birthday_view)
#views.py
def birthday_view(request,x,y,z):
    html = "生日为%s年%s月%s日"%(x,y,z)
    return HttpResponse(html)
#def birthday2_view(request,z,y,x):
#    html = "生日为%s年%s月%s日"%(x,y,z)
#    return HttpResponse(html)

请求相应

定义:请求是指浏览器端通过协议HTTP协议发送给服务器端的数据

​ 响应是指服务器收到接收到请求后做相应的处理后再回复给服务器端的数据

​ 起始行>headers>body

请求方法:

GET:请求指定的页面信息,并返回实体主体

HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

POST:指定资源提交数据进行处理请求。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改

PUT:从客户端向服务器传送的数据取代指定的文档的内容

DELETE:请求服务器删除指定的页面。

HTTP/1.1协议中预留给能够将连接改为管道方式的6

CONNECT:代理服务器。

OPTIONS:允许客户端查看服务器的性能。

TRACE:回显服务器收到的请求,主要用于测试或诊断。

COOKIES:Python字典,包含所有的cookie,键和值都为字符串 session:似于字典的对象,表示当前的会话

body:字符串,请求体的内容(POST或PUT) scheme:请求协议('http'/'https')

request.get_full_path():请求的完整路径

request.META:请求中的元数据(消息头)

-request.META['REMOTE_ADDR']:客户端IP地址

#utls.py
path('test_request',views.test_request)
#views.py
def test_request(request):
    print('path info is',request.path_info)
    print('method is',request.method)
    print("querystring is",request.GET)
    print("",request.get_full_path())
    return HttpResponse('test request ok')
#在终端会输出一下信息
	path info is /test_request
	method is GET
	querystring is <QueryDict: {'a': ['1'], 'b': ['1']}>

响应

​ 起始行>headers>body

HTTP状态码的英文为HTTP Status Code

常见HTTP状态码:

-200-请求成功

-301-永久重定向-资源(网页等)被永久转移到其他URL

-302-临时重定向

-404-请求的资源(网页等)不存在

-500-内部服务器错误

构造函数格式:

​ HttpResponse(content = 响应体,content_type = 响应体数据类型,status = 状态码) 状态码默认200

作用:

​ 向客户端浏览器返回响应,同时携带响应体内容

GET请求和POST请求

GET

:统一由视图函数接收请求,通过判断request.method区分具体请求动作

样例:

if request.method == 'GET':
    #处理GET请求时的业务逻辑
elif request.method == 'POST':
    #处理POST请求的业务逻辑
else:
    #其他请求业务逻辑

浏览器地址栏输入URL、超链接、form表单中的method为get 产生GET请求的场景

URL格式:xxx?参数名1 = 值1 &参数名2=值2

http://127.0.0.1:8000/test_request?a=1&b=1

#urls.py
path('test_get_post',views.test_get_post)
#views.py
def test_get_post(request):
    if(request.method == 'GET'):
       print(request.GET['a'])
   		#应用:问卷调查 from get 兴趣爱好——复选框
       	#127.0.0.1:8000/test_get_post?a=1&a=2&a=3&a=4&a=5
       print(request.GET.getlist('a'))
   
       print(request.GET.get('c','no c'))
    elif request.method == 'POST':
        pass
    else:
        pass
    return HttpResponse('--test get post is ok--')
#127.0.0.1:8000/test_get_post?a=1&b=1

POST

一般用于向服务器提交大量/隐私数据数据

#定义全局变量
POST_FROM = '''
<from method='post' action='/test_get_post'>
	用户名:<input type='text' name = 'uname'>
    <input type = 'submit' value = '提交'>
</from>
'''
#学习阶段出现403解决办法!!!
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
   #注释掉该行——> 'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
def test_get_post(request):
    if (request.method == 'GET'):
        #print(request.GET['a'])
        # 应用:问卷调查 from get 兴趣爱好——复选框
        # 127.0.0.1:8000/test_get_post?a=1&a=2&a=3&a=4&a=5
       # print(request.GET.getlist('a'))
       # print(request.GET.get('c', 'no c'))
        return  HttpResponse(POST_FROM)
    #先GET请求进入该操作——>return POST_FROM 请求 执行下一个elif操作
    elif request.method == 'POST':
        #用户处理提交数据
        print('uname is',request.POST['uname'])#这在命令行输出的内容
        return HttpResponse('post is ok')
    else:
        pass
    return HttpResponse('--test get post is ok--')

Django的设计模式及模板层

MVC和MTV

image-20221116234940237

image-20221116235150270

模板:1.是可以根据字典数据动态变化html页面

​ 2.模板可以根据视图中传递的字典数据动态生成相应的HTML页面

模板创建:

loader方法

  1. 在项目下创建一个templates文件夹

  2. 在settings.py中TEMPLATES'DIRS': [os.path.join(BASE_DIR,'templates')],

  3. views.py中

    def test_html(request):
            #方案1
        from django.template import loader
        t = loader.get_template('test_html.html')
        html = t.render()
        return HttpResponse(html)
    
    

    4.urls.py中

      path('test_html',views.test_html)
    

    5.在文件夹templates中建test_html.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>我是模板层的~~~~~~~</h3>
    </body>
    </html>
    

render()直接加载并响应模板

只在views.py中改(相对于上面的)

def test_html(request):
    #方案2
    from django.shortcuts import render
    return render(request,'test_html.html')

视图函数与模板之间的交互

视图函数可以将python变量封装到字典中传递到模板

模板中,我们可以用变量{{变量名}}的语法 调用视图传进来的变量

def xxx_view(request):
    dic = {
        "变量1":"值1"
        "变量2":"值2"
    }
    request render(request,'xxx.html',dic)
def test_html(request):
    #方案2
    from django.shortcuts import render
    dic = {'username':'gouxiaonao','age':18}
    return render(request,'test_html.html',dic)

#html文件
<h3>{{ username}}是模板层的~~~~~~~</h3>

模板层-变量

能传到模板中的 数据类型 : str, int, list数组, tuple 元组, dic 字典, func 方法, obj 类实例化的对象

模板中使用变量法:

{{变量名}}

{{变量名. index}}

{{变量名.key}}

{{对象.方法}}

{{函数名}}

#views.py中
def test_html_param(request):
    dic = {}
    dic['int'] = 88
    dic['str'] = 'apple'
    dic['listpp'] = ['Tom','Jack','Lily']
    dic['dict'] = {'a':9,'b':8}
    dic['func'] = say_hi
    dic['class_obj'] = Dog()
    return render(request,'test_html_param.html')
def say_hi():
    return 'hahaha'
class Dog:
    def say(self):
        return 'wowowo'
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>int 是 {{ int }}</h3>
<h3>str 是 {{ str }}</h3>
<h3>lst 是 {{ listpp }}</h3>
<h3>lst.0 是 {{ listpp.0 }}</h3>
<h3>dict 是 {{ dict }}</h3>
<h3>dict['a'] 是 {{ dict.a }}</h3>
<h3>function 是 {{ func }}</h3>
<h3>class_obj 是 {{ class_obj.say }}</h3>
</body>
</html>
#urls.py文件
path('test_html_param',views.test_html_param)

三者的关系:输入http://127.0.0.1:8000/test_html_param》对应urls.py重点path》找到views中的test_html_param函数def》该函数中有一定的数据dic字典》将这些字典发送给test_html_param.html文件》html文件中使用{{}}方式直接引用dic中的数据!

模板标签

作用:将一些服务器端的功能嵌入到模板中,例如流程控制等。

{% 标签%}

{%结束标签%}

def test_if_for(request):
    from django.shortcuts import render
    dic = {}
    dic['x'] = 10
    dic['list'] = {'小米','小航','小度'}
    return render(request,'test_if_for.html',dic)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试 if 和 for</title>
</head>
<body>
{% if x > 10 %}
今天ok
{% elif x < 10 %}
今天还ok
{% endif %}
{% for name in list%}
   {% if forloop.first %}++++++{% endif %}
    <p> {{forloop.counter}}{{name}}</p>
    {% if forloop.last %} ====={% endif %}
{%empty%}
    当前无数据
{%endfor%}
    
    
    
</body>
</html>

练习:if标签计算器

def mycal(request):
    if request.method == "GET":
        return render(request,'mycal.html')
    elif request.method == 'POST':
        x = int(request.POST['x'])
        y = int(request.POST['y'])
        op = request.POST['op']
        result = 0;
        if op == 'add':
            result = x+y
        elif op == 'sub':
            result = x-y
        elif op == 'mul':
            result = x*y
        elif op == 'div':
            result = x/y
        return render(request,'mycal.html',locals())
<form action="/mycal" method="post">
    <input type="text" name = "x" value = "{{x}}">
    <select name = "op">
        <option vaule = "add"{% if op == "add" %} selected {% endif %}>+加</option>
    <option value = "sub" {% if op == 'sub' %} selected {% endif %} >-减 </option>
        <option value = "mul" {% if op == 'mul' %} selected {% endif %} >-乘 </option>
        <option value = "sub" {% if op == 'div' %} selected {% endif %} >-除 </option>
    </select>
    <input type="text" name = "y" value = "{{y}}">=<span>{{ result }}</span>
    <div><input type = "submit" value = "开始计算"></div>
</form>

模板层-过滤器

过滤器

定义:在变量输出时对变量的值进行处理

lower将字符串转换为全部小写

upper 转换成大写

safe 默认不对变量内的字符串进行html转义(加safe后可执行html代码)

add: "n" 将value的值增加n

truncatechars:'n'如果字符串字符多于指定的字符数量,那么会被截断。截断的子字符串将以可翻译的省略号序列("...")结尾

<h3>str 是 {{ str|lower }}</h3>

模板的继承

模板继承可是父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块。

  1. 定义父模板中的块block标签
  2. 标识出哪些子模块中是允许被修改的
  3. block标签:在父模板中定义,可以在子模板中覆盖

注意:模板继承时,服务器端的动态内容无法继承

子模板中:

  1. 继承extends 标签

​ {%extends 'base.html'%}

  1. 子模板重写父模板中的内容块

    		{%block block_name%}
    

​ #这里写可更改的内容

​ {% endblock %}

def base_view(request):
    return render(request,'base.html')
def music_view(request):
    return render(request,'music.html')
 def sport_view(request):
    return render(request,'sport.html')
//父类html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block mytitle %}
    <title>主页</title>
    {% endblock %}
</head>
<body>
<a href = "/music_index">音乐频道</a>
<a href = "/sport_index">体育频道</a>
<br>
{% block info %}
这是主页
{% endblock %}
<br>
<h3>有问题请</h3>
</body>
</html>

//子类html
{% extends 'base.html' %}
{% block mytitle %}
<title>音乐频道</title>
{% endblock %}

{% block info%}
    欢迎来到音乐频道
{% endblock %}

url反向解析

代码中url出现位置

一、
1. <a href = 'url'>超链接</a>
#点击后 页面跳转至url
2.<form action = 'url' method = 'post'>
    #form表单中的数据 用post方法提交至url
</form>
二、
视图函数中-302跳转 HttpResPonseRedirect('url')
将用户地址栏中地址跳转到url

书写规范

绝对地址:http://127.0.0.1:8000/

相对地址:

​ "/music_index" 1.有'/'开头的相对地址,地址ip+端口,http://127.0.0.1:8000/page/3http://127.0.0.1:8000/page/1。2.没有'/'开头的相对地址,http://127.0.0.1:8000/page/3,“test_url_result,”http://127.0.0.1:8000/page/test_url_result

def test_url(request):
    return render(request,'test_url.html')
def test_url_result(request):
    return HttpResponse('---test url res is ok')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试URL</title>
</head>
<body>
<a href = "http://127.0.0.1:8000/test_url_result">绝对地址</a>
<a href = "/test_url_result">带'/'的相对地址</a>
<a href = "test_url_result">不带'/'的相对地址</a>
</body>
</html>
#urls.py
  #http://127.0.0.1:8000/test/url
    path("test/url",views.test_url),
    path("test_url_result",views.test_url_result)

反向解析

url反向解析是指视图或模板中,用path定义的名称来动态查找或计算出相应的路由

path函数的语法:path(route,views,name = "别名")

模板中:{% url 'page' '400' %}

  
def test_url_result(request,age):
    return HttpResponse('---test url res is ok')
path("test_url_result/<int:age>",views.test_url_result,name = 'tr')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试URL</title>
</head>
<body>
<a href = "http://127.0.0.1:8000/test_url_result">绝对地址</a>
<a href = "/test_url_result">带'/'的相对地址</a>
<a href = "test_url_result">不带'/'的相对地址</a>
    
<br>
<a href = "{% url 'tr' '100'%}">url反向解析版本</a>
</body>
</html>

在views.py中

def test_url_result(request,age):
    #302 跳转
    from django.urls import reverse
    url = reverse('base_index')
    return HttpResponseRedirect(url)
    #return HttpResponse('---test url res is ok')
#注意:要在首部 from django.http import HttpResponseRedirect

#urls.py
    path('base_index',views.base_view,name = 'base_index'),
    #加一个别名!!!方便调用

静态文件

静态文件:图片、css、js、音频、视频

#file:setting.py
#保存的是静态文件在服务器端的存储位置“BASE_DIR”
STATICFILES_DIRS = (
	os.path.join(BASE_DIR,"static"),
)
方法一:
<body>
<img src="http://127.0.0.1:8000/static/image/46dc90c5-2195-44fd-9d64-c4b54f7a831a.jpeg" alt="ji" width="200px" height="200px">
<img src="/static/image/46dc90c5-2195-44fd-9d64-c4b54f7a831a.jpeg" alt="ji" width="200px" height="200px">
</body>
方法二:
{% load static %}
<img src="{% static 'image/test.jpg'%}" width="200px" height="200px">
#setting.py中
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
#views.py中
  path('test_static',views.test_static),
#urls.py中
from django.shortcuts import render
def test_static(request):
    return render(request,'test_static.html')

django应用及分布式路由

应用:

​ 在Django项目中是一个独立的业务模块,可以包含自己的路由、视图、模板、模型。

创建应用

  1. 用manage.py 中的子命令startapp创建引用文件夹python manage.py startapp music
  2. 在setting.py的INSTALLED_APPS列表中配置安装此应用

image-20221124130125169

image-20221124130144352

image-20221124130314463

分布式路由:

可以在主路由配置文件(urls.py)中不处理用户具体路由,主路由有配置问价的可以做请求的分发(分布式请求处理)。具体的请求可以由各自的应用来处理。

添加分布路由步骤

#主路由urls.py中
from django.urls import path, include
path('music/',include('music.urls'))

#music.urls中
from django.urls import path
from . import views
urlpatterns = [
    # http://127.0.0.1:8000/music/index
    path('index',views.index_view)
]
#music.views中
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def index_view(request):
    return HttpResponse("这是音乐频道");

应用下的模板

应用内部可以配置模板目录

  1. 应用下手动创建templates文件夹

  2. setting.py中开启 应用模板功能

    1. TEMPLATE配置项中的'APP_DIRS'值为True即可

    应用下templates 和 外层templates都存在时,django得查找模板规则

    1. 优先查找外城templates目录下的模板
    2. 按INSTALLED_APPS配置下的应用顺序 逐层查找(如果在templates中创建目录,则可以避免因顺序导致的错乱)
def news_index(request):
    # return HttpResponse("这是新闻界面")4
    return render(request, 'news/index.html')
    #这是在templates目录下创建news文件夹 放入index.html应用方法

模板层及ORM介绍

配饰mysql 服务 
1. 自己电脑上需要先安装mysql (下载地址)https://dev.mysql.com/downloads/mysql/
2.配置环境变量及其后面步骤(https://blog.csdn.net/weixin_42869365/article/details/83472466)

运行MySQL在pycahrm中
1.首先需要在终端中在mysql里创建项目
create database mysite3,需要创建 数据库后才能执行

再 看下面

创建 数据库项目

image-20221202111218084

MySQL服务改密码操作

image-20221202110146420

启动服务

net start mysql

安装mysqlclient

创建数据库

进入mysql数据库执行(mysql -u root -p)

​ creat database 数据库名 default charset utf8

​ 通常数据库名跟项目名保持一致

setting.py里进行数据库的配置

​ 修改DATABASE配置项的内容,由sqlite3变为mysql

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'mysite3',
        'USER':'root',
        'PASSWORD':'123456',//这个需要和你创建的mysql密码一致
        'HOST':'127.0.0.1',
        'PORT':'3306'#端口号
    }
}
  • 什么是模型:模型是一个python类,它是由django.models.Model派生出的子类
  • 一个模型类代表数据库中的一张数据表
  • 模型类中每一个类属性都代表数据库中的一个字段。
  • 模型是数据交互的接口,是代表和操作数据库的方式和方法

ORM:

即对象关系映射,对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。它允许使用类和对象对数据库进行操作,从而避免通过SQL语句操作数据库。

作用:

  1. 建立模型类和表之间的对应关系,允许我们通过面向对象方式来操作数据库。

  2. 根据设计的模型类生成数据库中的表格

  3. 通过简单的配置就可以进行数据库的切换

image-20221126224439764

创建一个模型

#1、创建应用
#2、在应用中models.py中编写模型类
#3、创建模型类
from django.db import models
class 模型类名(models.Model):
    字段名 = models.字段类型(字段选项)
 #实操   

from django.db import models
# Create your models here.

class Book(models.Model):
    title = models.CharField('书名',max_length = 50,default='')
    price = models.DecimalField('价格',max_digits=7,decimal_places=2)    
#4、再执行,生成相应的文件,并迁移同步(终端中)
python manage.py startapp bookstore#创建应用
#执行 命令,迁移数据到Mysql中
python manage.py makemigrations
python manage.py migrate

添加新字段

解决:模型类中添加 对应 类属性

​ 执行数据库迁移

模型类——字段类型

BooleanField():

​ 数据库类型:tinyint(1)

​ 编程语言中:True 或 False来表示值

​ 在数据库中:使用1或0来表示具体的值

CharField():

​ 数据库类型:varchar

​ 注意:必须要指定max_length参数值

DateField():

​ 数据库类型:date

​ 作用:表示日期

​ 参数:auto_now:每次保存对象时,自动设置该字段为当前时间(取值:True/False)。

​ auto_now_add:当对象第一次被创建时自动设置当前时间(取值:True/False).

​ default:设置当前时间(取值:字符串格式时间如:'2019-6-1')

三选一

DateTimeField():日期时间

FloatField():double类型

DecimalField():小数,跟前相关的。max_digits位数总数,decimal_places小数点后的数字数量

EmailFIeld():varcahr, 存邮箱

IntegerField():int 编程语言和数据库中使用整数

ImageField():varchar(100)图片的路径

TextField():longtext表示不定长的字符数据

ORM-基础字段及选项2

模型类-Meta类(内部类)

from django.db import models
# Create your models here.

class Book(models.Model):
    title = models.CharField('书名',max_length = 50,default='')
    price = models.DecimalField('价格',max_digits=7,decimal_places=2)  
    class Meta:
        db_table = 'book'

ORM-基本操作-创建数据

数据库中django_migrations 表记录了migrate的"全过程",项目各应用中的migrate文件应与之对应,否则migrate会报错

管理对象

进入 Django Shell 交互环境 python manage.py shell

方案一:添加表的内容

image-20221203203103565

image-20221203203112762

方案二:

image-20221203204050692

image-20221203204058894

ORM-查询操作

查询语句

数据库 的查询需要使用管理器对象进行

通过MyModel.objects管理器方法调用查询方法

all():查询全部记录,返回QuerySet查询对象

get():查询符合条件的单一记录

filter():查询符合条件的多条记录

exclude():查询符合条件之外的全部记录

(首先需要进入 到 shell 中)

from bookstore.models import Book
books = Book.objects.all(); // 等同于 select * from table
for book in books:
    print("书名",book.title,"出版社",book.pub)

在模型类中定义__str__方法

    def __str__(self):
        return '%s%s%s%s' % (self.title,self.pub,self.price,self.market_price)

//使用方法

image-20221204193437965

Values('列1','列2')

MyModel.objects.values(...) 输入 查询值

字典

image-20221204194049399

Values-list

元组

order_by() 默认是按升序,若是 降序 加"-"负号

image-20221204194337915

实操项目

#djangoProject1\urls.py
    path('bookstore/',include('bookstore.urls'))
#bookstore\urls.py
	from django.urls import path
	from . import views
		urlpatterns = [
   			 path('all_book',views.all_book)
        ]
#bookstore\views.py
	from django.shortcuts import render
	from .models import Book
	# Create your views here.
	def all_book(request):
    	all_book = Book.objects.all()
    	return render(request,'bookstore/all_book.html',locals())
#bookstore/templates/bookstore/all_book.html
	<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>查看所有书籍</title>
</head>
<body>
<table border="1">
       <tr>
           <th>id</th>
           <th>title</th>
           <th>pub</th>
           <th>price</th>
           <th>market</th>
           <th>op</th>
       </tr>
    <tr>
        {% for book in all_book %}
        <tr>
            <td>{{ book.id}}</td>
            <td>{{book.title}}</td>
            <td>{{ book.pub }}</td>
            <td>{{ book.price }}</td>
            <td>{{ book.market_price }}</td>
            <td>
                <a href="">更新</a>
                <a href="">删除</a>
            </td>
        </tr>
        {% endfor %}
    </tr>
</table>
</body>
</html>

条件查询

MyModels.objects.filter(),返回值:QuerSet容器对象

from bookstore.models import 
books = Book.objects.filter(pub = '清华大学出版社')
for book in books:
    print("书名",book.title)

.exclude(条件):返回不包含 此条件的 全部 数据集

.get(条件):返回满足条件的唯一一条数据(如果 查询结果 多于一条 或没有数据,则会报错!)

非等值查询——查询谓词

__exact:等值匹配

Author.objects.filter(id__exact = 1)

等同于 select * from author where id = 1

__contains:包含指定值

__startswith:以xxx开始

__endswith:以xxx结束

__gt:大于指定值

__gte:大于等于

__lt:小于

__lte:小于等于

__in:查找数据是否在指定范围内

__range:查找数据是否在指定的区间范围内

更新操作

单个数据修改

1.差 -通过get() 得到要修改的实体对象

2.改 -通过 对象.属性 的方式修改数据

3.保存 -通过 对象.save() 保存数据

image-20221204203920360

查看结果:

image-20221204203901361

多个数据修改

直接调用QuerySet的update(属性 = 值)实现批量修改

#将 id 大于3 的所有图书 价格定为 0元
books = Book.objects.filter(id__gt = 3)
books.update(price = 0)
#将所有书的零售价定为100元
books = Book.objects.all()
books.update(market_price = 100)

实操:制作一个能 反馈的 图书管理系统

image-20221204210820375

image-20221204210829026

删除操作

单个数据删除

​ 方法:找到——再删除

try:
    auth = Author.objects.get(id = 1)
    auth.delete()
except:
    print(删除失败)

批量删除

方法:找到符合查询结果集中满足条件的全部QuerSet查询集合对象

auths = Author.objects.filter(age__gt = 65)
auths.delete()

伪删除

添加布尔类型字段(is_active),默认为true

 is_active = models.BooleanField('是否活跃',default=True)
mysql> select * from book;
+----+--------+-------+--------------+----------------+-----------+
| id | title  | price | market_price | pub            | is_active |
+----+--------+-------+--------------+----------------+-----------+
|  1 | python | 26.00 |        25.00 | 浙江工商大学   |         1 |
|  2 | Django | 19.00 |        12.00 | 杭州商学院     |         1 |
|  3 | JQuery | 19.00 |         9.90 | 机械工业出版社 |         1 |
|  4 | Linux  | 70.00 |        78.00 | 清华大学出版社 |         1 |
+----+--------+-------+--------------+----------------+-----------+
4 rows in set (0.00 sec)

实操:

#views.py
def delete_book(request):
        #通过获取字符串 book_id 拿到要删除的book的id
        book_id = request.GET.get('book_id')
        if not book_id:
            return HttpResponse('---请求异常')
        try:
            book = Book.objects.get(id = book_id,is_active=True)
        except Exception as e:
            print('---delete book  get error %s'%(e))
            return HttpResponse('---The book id is error')
        #将其is_active改成False
        book.is_active = False #这里就是在对数据库里的数据进行操作了
        book.save()#改后记得 保存!!!
        # 302跳转至all_boo   
#url.py
from django.urls import path
from . import views

urlpatterns = [
    path('all_book',views.all_book),
    path('update_book/<int:book_id>',views.update_book),
    path('delete_book',views.delete_book),
]
#all_book.html
<a href="/bookstore/update_book/{{ book.id }}">更新</a>
                <a href="/bookstore/delete_book?book_id={{ book.id }}">删除</a>

F对象和Q对象

F对象:

一个F对象代表数据库中某条记录的字段信息

作用:通常是对数据库中的字段值再不获取的情况下进行操作

​ 用于类属性(字段)之 间的比较

from django.db.models import F
F('列名')

实例:更新Book实例中所有的零售价涨10元

Book.objects.all().update(market_price = F('market_price') + 10)# += 10

image-20221205233210836

image-20221205233544293

Q:

当获取查询结果集 使用复杂的逻辑或 |、逻辑非 ~ 等操作时可以借助于Q对象进行操作

需要 导入 django.db.models

例如:想要找出定价低于20元 或 清华大学出版社的全部书籍,可以写成

Book.objects.filter(Q(price__lt = 20) | Q(pub = "清华大学出版社"))

image-20221205234401038

image-20221205234443457

聚合查询和原生数据库操作

聚合查询

​ 对一个数据表中的一个字段的数据进行部分或全部进行统计查询

整表聚合

分组聚合

image-20221208124602424

image-20221208125254513

image-20221208125504204

image-20221208125512570

原生数据库操作

查询:使用MyModel.objects.raw()进行 数据库查询操作查询

语法:MyModel.objects.raw(sql 语句,拼接参数)

返回值:RawQuerySet 集合 对象【只支持基础操作,如循环】

books = models.Book.objects.raw('select * from bookstore_book')
for book in books:
    print(book)

*使用原生语句时小心 SQL注入

image-20221208131338180

admin后台管理

admin后台管理1

image-20221208131948341

admin2

注册自定义模型类

#在admin.py文件中添加自己的 后台模板
from django.contrib import admin
from .models import Book

# Register your models here.
admin.site.register(Book)

image-20221209204823778

模型管理器类

作用: 为后台管理界面添加便于操作的新功能

说明: 后台管理器类须继承自django.contrib.admin里的ModelAdmin类

image-20221209204522250

#在admin.py文件中添加自己的 后台模板
from django.contrib import admin
from .models import Book

# Register your models here.
class BookManager(admin.ModelAdmin):
    list_display = ['id','title','pub','price']
     #控制list_display中的字段,哪些可以链接到
    list_display_links = ['title']
     #添加过滤器
    list_filter = ['pub']
       #添加搜索框[模糊查询]
    search_fields = ['title']
        #添加可在列表页编辑的字段
    list_editable = ['price']
admin.site.register(Book,BookManager)

image-20221209204746026

关系映射(关系)

一对一模型

一对多、多对多

image-20221209211737727

image-20221209214113168

image-20221209214129575

实操:

image-20221209214435719

image-20221209214601587

image-20221209214658754

一对多模型

:一个学校有多个班级,一个班级有多个学生,一本图书只能属于一个出版社,一个出版社允许出版多本图书。 一对多:需要确定具体角色,多表上设置外键

class A(models.Model):
    
    
class B(models.Model):
    属性 = models.ForeignKey('***',on_delete = xx)
    #ForeignKey 必须指定为 on_delete模型
#实操 otm - models.py 中
from django.db import models

# Create your models here.
class Publisher(models.Model):
    name = models.CharField('出版社名称',max_length=50);

class Book(models.Model):
    title = models.CharField('书名',max_length=11)
    publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE)

创建数据值:

image-20221211000629620

image-20221211000856453

多对多模型

image-20221211001302302

#创建
from django.db import models

# Create your models here.
class Author(models.Model):
    name = models.CharField('姓名',max_length=11)

class Book(models.Model):
    title = models.CharField('书名',max_length=11)
    author = models.ManyToManyField(Author)

创建数据

image-20221211003025815

from mtm.models import *
>>> a1 = Author.objects.create(name = '孙老师')
>>> b1 = a1.book_set.create(title = 'python训练书')
>>>
>>>
>>> a2 = Author.objects.create(name = '刘老师')
>>> b1
<Book: Book object (1)>
>>> a2.book_set.add(b1)
>>>

image-20221211003726760

image-20221211003739853

cookies 和 session

cookies 和 session 都是为了保持对话状态而诞生的两个存储技术

cookies

:是保存在客户端浏览器上的存储空间。在浏览器上以键-值队形式(ASCII码值)存放。且都带有生命周期。cookies中的数据都是按域存储隔离的,不同的域之间无法访问。cookies的内部的数据会在每次访问此网络时都会携带到服务器端,如果cookies过大会降低相应速度。

image-20221213233420111

image-20221213234236402

path('set_cookies',views.set_cookies),
def set_cookies(request):
    resp = HttpResponse("set cookies is ok")
    resp.set_cookie('uuname','gxn',500)
    return resp

获取

image-20221213234339076

path('get_cookies',views.get_cookies),
def get_cookies(request):
    value = request.COOKIES.get('uuname')
    return HttpResponse('value is %s'%(value))

image-20221213234814952

session

在服务器上开辟一段空间用于保存浏览器和服务器交互时的重要诗句。

实现方式:使用session需要在浏览器客户端启动cookie,且在cookie存储sessionid

​ 每个客户端都可以在服务器端有一个独立的Session

​ 注意不同的请求之间不会共享这个数据,与请求者一一对应。

image-20221215125147079

session的使用

session对于象是一个类似于字典的SessionStore类型的对象,可以用类似于字典的方式进行操作

session能够存储如字符串,整型,字典,列表等

1、保存session的值到服务器

​ request.session['KEY'] = VALUE

2、获取session的值

​ value = request.session['KEY']

​ value = request.session.get('KEY',默认值)

3、删除session

​ del request.session['KEY']

image-20221215131011714

image-20221215131348829

标签:python,py,request,笔记,Django,models,html,test,path
From: https://www.cnblogs.com/Hygge1024/p/18060825

相关文章

  • Python 第三方库安装国内镜像汇总
    Python第三方库安装国内镜像汇总: 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple阿里云: http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/华中科技大学: http://pypi.hustunique.com/山东理工大学: http://pyp......
  • aiofiles,一个异步测试的 Python 库!
    什么是aiofiles库?aiofiles是一个异步文件操作库,提供了一种简单而强大的方式来执行文件操作,包括打开文件、读取文件、写入文件等。aiofiles库是建立在asyncio之上的,它允许开发人员在异步程序中执行文件操作,而不会阻塞事件循环。安装aiofiles库pipinstallaiofiles基本......
  • CF576E 笔记
    前置知识:线段树分治。题意给定一个\(n\)个点\(m\)个点的图,有\(k\)种颜色,初始时每条边都没有颜色。有\(q\)组询问,每组询问\((i,c)\)表示把第\(i\)条边颜色改成\(c\),然后判断:所有颜色为\(c\)的边拉出来是否是一个二分图。如果是就输出YES;否则输出NO,并撤销该操......
  • MYSQL学习笔记4: DML数据操作(增删改)
    DML数据操作(增删改)INSERT插入给指定字段插入数据insertinto表名(字段1,字段2...)values(值1,值2);向itcast的worker表的制定字段中插入一条新数据insertintoworkers(id,workNo,name,gender,age,idCard,entryDate)values(1,'1','hikari39','女',2......
  • MYSQL学习笔记3: DDL表修改
    DDL表修改在表中添加新字段#格式ALTERTABLE表名ADD字段名(长度)[COMMENT注释][约束];#在itcast表中新建一个nickname字段altertableitcastaddnicknamevarchar(20)comment'昵称';修改字段数据类型altertable表名modify字段名新数据类型(长度);修改字段名......
  • python版本简易阿里云ddns
    importosimportsysfromdatetimeimportdatetimefromalibabacloud_alidns20150109.clientimportClientasDNSClientfromalibabacloud_tea_openapiimportmodelsasapi_modelsfromalibabacloud_alidns20150109importmodelsasdns_modelsimportrequestsclassDDN......
  • MYSQL学习笔记2: 数据类型
    数据类型数值类型TINYINTUNSIGNED无符号的tinyintDOUBLE(4,1)整体长度为4,小数位数为1的DOUBLE数据字符串类型CHAR(10)定长字符串,最多存储10个字符,占用10个字符的内存VARCHAR(10)变长字符串,最多存储10个字符,根据实际字符的长度计算内存空间对于CHAR和VARCHA......
  • python3代码转换成docker镜像启动
    1.打包成docker镜像来使用切到Tags,搜索3.11选择python:3.11.4-slim-bullseye2.在压测脚本的根目录中,创建Dockerfile文件: FROMpython:3.11.4-slim-bullseyeWORKDIR/opt/appCOPYrequirements.txt./ENVhost=nullENVport=nullENVonlyResetJob=nullRUNpip......
  • 第101天-python-flask简介
    1.flask1.1、flask简介Flask简介:Flask诞生于2010年,是用Python语言基于Werkzeug工具箱编写的轻量级Web开发框架。Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。其WSGI工具箱采用Werkzeug(路由......
  • Vue学习笔记40--脚手架项目架构分析
    脚手架项目架构分析1.babel.config.js——babel的控制文件,用于ES6转ES5(一般不需要程序员进行配置,如想研究请查看babel官网)module.exports={presets:['@vue/cli-plugin-babel/preset']}2.package.json——包信息说明,例如:项目名称、版本、采用的依赖、库文件......