HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪“部分,以及哪部分内容首先显示(如文本先于图形)等。
# -*- coding:utf-8 -*-
# created by Alex Li - 路飞学城
import socket
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('localhost', 8000))
sock.listen(5)
while True:
# 等待浏览器访问
conn, addr = sock.accept()
# 接收浏览器发送来的请求内容
data = conn.recv(1024)
print(data)
# 给浏览器返回内容
conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n")
conn.send("电脑前的你长的真好看!
".encode("utf-8"))
# 关闭和浏览器创建的socket连接
conn.close()
if __name__ == "__main__":
main()
from wsgiref.simple_server import make_server
def run_server(environ,start_response):
"""
:param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
:param start_response: 响应相关
:return:
"""
start_response("200 OK",[('Content-Type','text/html;charset=utf-8')])
return [bytes('Hello world!
',encoding='utf-8')]
if __name__ == '__main__':
httpd = make_server('localhost',8000,run_server)
httpd.serve_forever() # 死循环
from wsgiref.simple_server import make_server
def book(environ,start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
return [bytes('book page!
', encoding='utf-8')]
def cloth(environ,start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
return [bytes('cloth page!
', encoding='utf-8')]
pass
def url_dispacher():
urls = {
'/book':book,
'/cloth':cloth,
}
return urls
def run_server(environ,start_response):
"""
:param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
:param start_response: 响应相关
:return:
"""
request_url = environ.get("PATH_INFO") # 获取用户请求的url
url_list = url_dispacher() # 拿到所有url
if request_url in url_list:
func_data = url_list[request_url](environ,start_response)
return func_data # 真正返回数据给用户
else:
start_response("404 ",[('Content-Type','text/html;charset=utf-8')])
return [bytes('404,Page not found!
',encoding='utf-8')]
if __name__ == '__main__':
httpd = make_server('localhost',8000,run_server)
httpd.serve_forever() # 死循环
from wsgiref.simple_server import make_server
import re
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
def book(environ,start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
data = """
欢迎来到日本人专区
上路飞学城,看尽天下小片
"""
return [bytes(data, encoding='utf-8')]
def cloth(environ,start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
return [bytes('cloth page!
', encoding='utf-8')]
pass
def url_dispacher():
urls = {
'/book':book,
'/cloth':cloth,
}
return urls
def img_handler(request_url):
"""
:param request_url: static/imgs/testimg.gif
:return:
"""
img_path = re.sub('/static','/static_data',request_url)
img_abs_path = "%s%s"% (BASE_DIR,img_path)
if os.path.isfile(img_abs_path):
f = open(img_abs_path,"rb")
data = f.read() # 读取文件内容数据
return [data,0] # 0:成功读取,1:没有读取
return [None,1]
def run_server(environ,start_response):
"""
:param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
:param start_response: 响应相关
:return:
"""
request_url = environ.get("PATH_INFO") # 获取用户请求的url
url_list = url_dispacher() # 拿到所有url
if request_url in url_list:
func_data = url_list[request_url] (environ,start_response) # 调用相应的url函数
return func_data # 真正返回数据给用户
elif request_url.startswith("/static/"): # 表示图片
img_data,img_status = img_handler(request_url)
if img_status == 0: # 读取到图片数据
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
return [img_data]
else:
start_response("404 ",[('Content-Type','text/html;charset=utf-8')])
return [bytes('404,Page not found!
',encoding='utf-8')]
if __name__ == '__main__':
httpd = make_server('localhost',8001,run_server)
httpd.serve_forever() # 死循环
MVC 是一种使用 MVC (Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式
Django是一个MTV框架,其架构模板看上去与传统的MVC架构并没有太大的区别。
Django将MVC中的视图进一步分解为 Django视图(views.py) 和 Django模板(html文件)两个部分,分别决定“展现哪些数据”和“如何展现”,使得Django的模板可以根据需要随时替换,而不仅仅限制于内置的模板,至于MVC控制器部分,由Django框架的URLconf(urls.py)来实现。
MVC VIEWS 负责 业务逻辑处理+数据展示
MTV Views 业务逻辑处理
Templates 数据展示
打开终端(命令行界面)
确保你已经安装了Django。可以通过运行以下命令来检查Django是否已安装:
django-admin --version
如果没有安装Django,可以使用以下命令安装:
pip install django
创建项目。在终端中使用以下命令创建一个Django项目:
django-admin startproject project_name
把 “project_name” 替换为你想要的项目名称。这将在当前目录下创建一个名为 “project_name” 的文件夹,其中包含用于构建Django项目所需的文件和目录。
创建应用。在项目目录中使用以下命令创建一个Django应用:
django-admin startapp app_name
把 “app_name” 替换为你想要的应用名称。这将在项目目录下创建一个名为 “app_name” 的文件夹,其中包含用于构建Django应用的文件和目录。
进入项目目录。使用以下命令进入刚创建的项目目录:
cd project_name
这会将终端的当前工作目录切换到你的项目目录中。
运行开发服务器。在项目目录中,运行以下命令来启动Django的开发服务器:
python manage.py runserver 0.0.0.0:8000
这将运行开发服务器,默认在本地的8000端口上。
现在,你可以在浏览器中访问 http://localhost:8000/
来查看新创建的Django项目的初始页面。
这样就完成了在终端中创建一个Django项目的步骤。你可以根据需要在项目中添加应用、模型、视图等。
django-admin startproject my_site
项目目录结构
mysite
├── manage.py # 管理程序的文件,启动和结束等。
└── my_site
├── __init__.py
├── settings.py # 程序的配置文件
├── urls.py # 程序的路由系统,即:url和处理其函数的对应的关系
└── wsgi.py # 指定框架的wsgi
django-admin startapp app01
├── __init__.py 包
├── admin.py 数据库后台
├── apps.py #django 把项目和app 关联起来的一个文件
├── migrations #数据库相关
│ └── __init__.py
├── models.py # 数据库操作地方
├── tests.py # 单元测试
└── views.py # 业务逻辑代码
1。 urls.py 编写路由
2. 在views.py 写一个业务函数
2.1 编写业务 代码
2.2 通过HttpResponse 方法返回数据给前端
3. python manage.py runserver 0.0.0.0:8000
# 安装模块:pip install jinja2
from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update({
'static': static,
'url': reverse,
})
return env
# 项目默认配置django引擎
# 若需配置jinja引擎,需添加
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'environment':'django4.jinja2_env.environment', # django4-项目名称,jinja2_env-该项目下新建的jinja2_env.py
TEMPLATES = [ # 模版,html文件
# jinja2模板引擎 (在html文件中可以引用函数)
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [BASE_DIR/'templates'],
'APP_DIRS': True,
'OPTIONS': {
# 添加environment,并指定到jinja2_env文件中的environment
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
# django模板引擎
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR/"templates"], # html 文件夹的位置
'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',
],
},
},
]
"""注释"""
{# 单行注释 #}
{% comment %}
多行注释
{% endcomment %}
"""变量"""
<p>{{ name }}</p>
<p>{{ boddy.2 }}</p> # 列表:索引号取值
<p>{{ addr.city }}</p> # 字典
"""if语句"""
{% if age < 18 %}
...
{% elif age > 60 %}
...
{% else %}
...
{% endif %}
"""结合运算符"""
{% if age >= 18 and age < 60%}
{% if age >= 18 or age < 60%}
"""in"""
{% if 'movie' in boddy %}
...
{% endif %}
"""for循环语句"""
{% for b in boddy %}
...
{% endfor %}
"""empty用法"""
{% for b in boddy2 %}
...
{% empty %}
<p>boddy2为空或不存在</p>
{% endfor %}
"""下标"""
{% for foo in boddy %}
<p>
counter_{{ forloop.counter }} # 下标从1开始
counter0_{{ forloop.counter0 }} # 下标从0开始
revcounter_{{ forloop.revcounter }} # 下标颠倒从大到小
revcounter0_{{ forloop.revcounter0 }} # 下标颠倒从大到小(0)
</p>
{% endfor %}
"""嵌套语句"""
<table border="2" width="400">
{% for star in stars %}
{% for s in star %}
{{ s }}-
{{ forloop.parentloop.counter }}- # 父循环的下标
{{ forloop.counter }} # 本次循环下标
{% endfor %}
{% endfor %}
</table>
"""过滤器"""
<p>{{ age }}</p>
<p>{{ age|add:5 }}</p> # add:变量+5
<p>{{ age|add:-5 }}</p> # add:变量-5
<p>{{ name|first|upper }}</p> # 将变量name第一个字符串大写
<p>{{ name|last|lower }}</p> # 将变量name最后一个字符串小写
<p>{{ name|title }}</p>
<p>{{ name|truncatechars:3 }}</p> # 将变量name第三个字符串开始截断
<p>{{ boddy|join:'+' }}</p> # 列表转字符串
<p>{{ boddy2|default:'默认值' }}</p> # 若变量boddy2无值则设置默认值
<p>{{ dt|date:'y-m-d' }}</p> # 转成日期格式
<p>{{ dt|date:'Y-M-d' }}</p>
"""HTML转义"""
<p>{{ code|safe }}</p> # safe:将变量code字符串转义成html格式
{% autoescape on %} # 关闭自动转义
... # 自动转义字符串内容
{% endautoescape %}
{% autoescape off %} # 开启自动转义
...
{% endautoescape %}
<body>
<h2>jinja2模板语言</h2>
<hr>
{# 可调用python函数range #}
{% for i in range(1,10) %}
{{ i }}
{% endfor %}
</body>
</html>
# 模板快
{% block xxx%}
...
{% endblock %}
# 继承模板
{% extends 'xxx.html' %}
# 继承模板内容:block.super
{% block content %}
{# 默认情况下,子模板会覆盖父模板内容 #}
{# 若想继承父模板内容,需使用block.super #}
{{ block.super }}
{% endblock %}
# 导入其他模板文件:include
{% block head %}
{# 导入其他模板文件 #}
{% include 'xxx.html' %}
{% endblock %}
models ==> ORM
模型 -> 表
类结构 -> 表结构
对象 -> 表的一条数据
类属性 -> 表的字段
# 常用字段
CharField:用于存储字符串,可指定最大长度。
TextField:用于存储长文本字段,没有长度限制。
IntegerField:用于存储整数。
FloatField:用于存储浮点数。
BooleanField:用于存储布尔值,True或False。
DateField:用于存储日期。
DateTimeField:用于存储日期和时间。
FileField:用于存储文件,文件会被上传到指定目录。
ImageField:与FileField类似,但特定于存储图像文件。
# 常用属性
max_length:用于指定字段的最大长度。适用于CharField和TextField等字符串字段类型。
null:指定字段是否允许为空。默认为False,即不允许为空。对于关联字段(ForeignKey、OneToOneField等),默认值是True。
blank:指定字段在表单中是否可以为空。默认为False,即不能为空。对于关联字段,如果null=True,则默认值为True。
default:指定字段的默认值。
choices:用于定义字段的选项列表。适用于CharField和IntegerField等字段类型。例如:choices=[(1, ‘男’), (2, ‘女’)]
verbose_name:指定字段在后台管理界面中显示的名称。
related_name:用于指定反向关系的名称。适用于关联字段(ForeignKey、ManyToManyField等)。
unique:指定字段的值是否在数据库中唯一,默认为False。
help_text:用于在后台管理界面中显示字段的帮助文本。
auto_now:指定每次保存对象时自动更新字段的值为当前时间。适用于DateTimeField和DateField等日期时间字段类型。
auto_now_add:指定在创建对象时将字段的值设置为当前时间。适用于DateTimeField和DateField等日期时间字段类型。
editable:指定字段是否可编辑。默认为True,表示字段可以在后台管理界面中被编辑。
primary_key:指定字段是否为主键。默认为False。
db_index:指定是否在数据库中为字段创建索引。默认为False。
choices:定义了一个包含键-值对的元组,作为下拉菜单。
name / db_column:数据库中的字段名称。
upload_to:用于定义上传文件的存储路径。
# 注:每次写完模型或添加一个字段都需要进行一次数据迁移,将数据迁移到数据库中!
from django.db import models
class UserModel(models.Model):
# uid 会成为主键,原来默认的id不会创建
uid = models.AutoField(auto_created=True,primary_key=True)
# CharField:字符串类型
# unique:唯一
# db_index:数据库索引
name = models.CharField(max_length=20,unique=True,db_index=True)
# IntegerField:整数类型
# default:默认值
age = models.IntegerField(default=18)
# BooleanFieldL:bool类型
sex = models.BooleanField(default=True)
# TextField:文本框
# null=True:表示可以为空
# blank=True:在admin管理页面可以为空
info = models.TextField(null=True,blank=True)
# FloatField:小数
salary = models.FloatField(default=100000.521)
# DecimalField:十进制小数
# max_digits:最大长度
# decimal_places:小数点是几位
money = models.DecimalField(max_digits=4,decimal_places=2,default=10.52)
# settings.py
# 设置mysql
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "myBlog", # 数据库名
"USER": "root",
"PASSWORD": "12345678",
"HOST": "127.0.0.1",
"PORT": "3306",
}
}
# __init__.py(项目文件)
import pymysql
pymysql.version_info = (1, 4, 13, "final", 0) # mysqlclient版本问题
pymysql.install_as_MySQLdb()
同步ORM表结构到数据库(Models.py文件每次写完就需要进行迁移)
在项目中如果添加了一个字段,需手动同步到数据库,否则数据库报错没有该字段
数据库同步工具:migrations
1、生成迁移文件
# app01表示指定的app,若第一次执行,则可以默认不写
python manage.py makemigrations app01
python manage.py migrate
# settings.py
# 同步app设置,最后写入同步的app名
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
]
# urls.py
from django.urls import path,re_path
from app02 import views
urlpatterns = [
re_path(r'^articles/2003/$',views.article_archive1),
# year,month被封装为字典,所以函数形参需写该键值接收
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$' ,views.article_archive2),
# slug:匹配任意字符串
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[\w-]+)/$' ,views.article_archive3),
]
# views.py
def article_archive1(request):
return HttpResponse('静态article_2003')
def article_archive2(request,year,month):
return HttpResponse('动态article %s-%s'%(year,month))
def article_archive3(request,arg1,arg2,slug):
return HttpResponse('动态article %s-%s-%s'%(arg1,arg2,slug))
# urls.py
from django.urls import path
from app02 import views
# path匹配
urlpatterns = [
path('articles/' ,views.new_article1),
# str:除了'/'外都能匹配
path('articles//' ,views.new_article2),
path('articles///' ,views.new_article3),
# path:'/'也能匹配
path('articles/' ,views.new_article4),
]
# views.py
def new_article1(request,year):
return HttpResponse('新用法Path %s'%year)
def new_article2(request,year,date):
return HttpResponse('新用法Path %s %s'%(year,date))
def new_article3(request,year,month,arg):
return HttpResponse('新用法Path %s %s %s'%(year,month,arg))
def new_article4(request,arg):
return HttpResponse('新用法Path %s'%(arg))
# urls.py
urlpatterns = [
path('userdetail/' ,userdetail,name='myuserdetail'),
]
# views.py
def userdetail(request,uid):
user = userModel.objects.get(pk=uid) # pk:主键
return render(request,'userdetail.html',{'user':user}) # 将user参数传入html文件的user变量
# userdetail.html
<body>
<p>名字:{{ user.name }}</p>
<p>年龄:{{ user.age }}</p>
</body>
# urls.py
urlpatterns = [
path('app01/',include(('app01.urls','app01'),namespace='app01')),
]
# app01:urls.py
urlpatterns = [
path('userlist/',userlist,name='myuserlist'), #
path('userdetail/' ,userdetail,name='myuserdetail'),
]
# userlist.html
<body>
# 跳转到命名空间为app01下的myuserdetail的html( url/userdetail/id )
<a href="{% url 'app01:myuserdetail' user.id %}"></a>
</body>
# views.py
from django.shortcuts import redirect,reverse
# 重定向
def myredirect(request):
# return redirect('https://www.baidu.com')
# 反向解析
# redirect(reverse('myuserdetail'),args=(2,)) ==> 'userdetail/2/'
return redirect(reverse('myuserdetail',args=(2,))) # args传参
return redirect(reverse('myuserdetail',kwargs={'uid':2})) # 关键字传参
# 命名空间
return redirect(reverse('app01:myuserdetail',args=(2,))) # args传参
return redirect(reverse('app01:myuserdetail',kwargs={'uid':2})) # 关键字传参
# urls.py
from django.urls import path,include
urlpatterns = [
# 包括了app01和app02项目的urls
path('app01/',include("app01.urls")),
path('app02/',include("app02.urls"))
]
# urls.py
# 去除重复的部分url
extra_urls = [
path('/' , views.new_article2),
path('//' , views.new_article3),
path('' , views.new_article4),
]
urlpatterns = [
# 去除url重复的路径"articles"部分,匹配结果相同
path('articles',include(extra_urls))
]
# urls.py
urlpatterns = [
# 写一个字典,键表示实参名,值表示传入实参值
path('articles/' ,views.new_article1,{'version':'v1.0'}),
]
# views.py
# 获取参数version
def new_article1(request,year,version):
return HttpResponse('新用法Path %s-%s'%(year,version))
# views.py
from django.shortcuts import render,HttpResponse
def index(request):
print(request.scheme) # http
print(request.path) # /app02/index
print(request.method) # get
print(request.content_type) # text/plain
print(request.GET,request.POST) #
print(request.GET.get('username'),request.POST.get('username')) # 获取字典数据
print(request.FILES) # ]}>
print(request.META['REMOTE_ADDR']) # 127.0.0.1
print(request.META)
for k,v in request.META.items():
print(k,v)
print(request.get_host()) # localhost:8000
print(request.get_port()) # 8000
print(request.get_full_path()) # /app02/index
print(request.build_absolute_uri('user=abc/pwd=123')) # http://localhost:8000/app02/user=abc/pwd=123
print(request.COOKIES) # 浏览器cookies数据
print(request.session)
return render(request,'form.html')
# 项目的settings.py
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',
]
# 响应
from django.http import JsonResponse
# 1.返回字符串
return HttpResponse('OK')
# 2.返回模板:前后端不分离使用
return render(request,'index.html')
# 3.重定向:跳转页码
return HttpResponseRedirect("/")
# 4.返回JSON:前后端分离使用
return JsonResponse({"data":"hello"})
**content_type:**用于填充HTTP的数据类型
**status:**HTTP的状态码
# views.py
from django.shortcuts import HttpResponse
def index(request):
html = """
"""
res = HttpResponse(html,content_type="text/plain",status=404)
from django.shortcuts import HttpResponseRedirect,HttpResponsePermanentRedirecttt
def test(request):
return HttpResponseRedirect("/") # 临时定向到首页
return HttpResponsePermanentRedirecttt("/") # 永久定向到首页
# views.py
from django.views import View
# 该类会自动判断调用方法
class TestView(View):
def get(self,request):
return HttpResponse("Class View get request")
def post(self,request):
return HttpResponse("Class View post request")
pass
# urls.py
urlpatterns = [
path('class_view',views.TestView.as_view()) # 对于类需调用as_view方法
]
# views.py
# 类继承
class TestView2(TestView):
time = 10
# views.py
def download_file(request):
f = open('static_data/data.xls','rb')
res = HttpResponse(f.read(),content_type='application/vnd.ms-excel') # 文件类型为xls
res['Content-Disposition'] = 'attachment; filename="my_data.xls"' # 对下载的文件进行处理
return res
# views.py
from django.core.paginator import Paginator
def paginate(request,page=1):
per_page = 10
all_data = PersonModel.objects.all()
# 分页器
paginator = Paginator(all_data,per_page)
persons = paginator.page(page) # 获取第page页的数据
pages = range(1,per_page+1) # 页面范围,供遍历
data = {'persons':persons,'pages':pages}
return render(request,'paginate.html',data)
# urls.py
urlspattern = [
path('paginate//' ,paginate,name='paginate'),
]
python manage.py shell
from app01 import models
# 方法1,object.create创建对象,创建完后数据将自动提交保存到数据库
models.Account.object.create(
username = '小枫',
email='[email protected]',
password='12345678',
)
# 方法2,先创建数据,再通过save方法提交数据
new_obj = models.Account(
username = '小枫',
email='[email protected]',
password='12345678',
)
new_obj.save()
# 方法1,直接在对象里关联 account_id = id值
models.Article.objects.create(
title = '如何学Python',
content = '日复一日,坚持学习',
# 关联的键值必须加上_id
account_id = 1,
pub_date = '2023-7-31',
)
# 方法2,先各自创建表,再进行关联 a1.account = m1对象
# 先创建用户表
m1 = models.Account(
username='王五',
email='[email protected]',
password='213123',
)
m1.save()
# 再创建文章表
a1 = models.Article(
title='什么是chatggpt',
content='人工智能chatgpt',
pub_date='2022-10-12',
)
# 关联表
a1.account = m1
a1.save()
a1 = models.Article(
title='什么是chatggpt',
content='人工智能chatgpt',
account_id = 1,
pub_date='2022-10-12',
)
# tags.set,赋值tags对象id为1,3,5
a1.tags.set([1,3,5])
# tags.add,在原记录上加新值tags对象id为1,2,3
a1.tags.add(1,2,3)
articles = models.Article.objects.filter(content__contains='技术') # 过滤出含有关键词的文章
tag = models.Tag.objects.get(id=2) # 获取要关联的标签对象
for article in articles:
article.tags.add(tag) # 将标签关联到每篇过滤后的文章中
# __gt:大于
# 查询id大于5的Account对象
models.Account.objects.filter('id__gt=5')
# startswith:以什么开头
# 查询以密码为a开头的Account对象
models.Account.objects.filter('password__startswith='a')
# , : 和
# 查询id大于5的Account对象并且psw是123
models.Account.objects.filter('id__gt=5,password='123')
# 批量修改
models.Account.objects.filter(id__gt=1).update(password='1234556')
# 单条修改
a = models.Account.objects.get(id=1)
a.username = 'job'
a.save()
# 批量删除
models.Account.objects.filter(id__gt=1).delete()
# 单条删除
a = models.Account.objects.get(id=1)
a.delete()
gt:大于
it:小于
ite:小于等于
gte:大于等于
statswith:以什么开头
endswith:以什么结尾
contains:包含
models.Account.objects.filter(password__contains="1")
in:判断是否存在并返回
models.Account.objects.filter(id__in=(2,3))
range:区间过度,可对数字、日期进行过滤
import datetime
start_date = datetime.date(2022,12,15)
end_date = datetime.date(2023,8,1)
models.Account.objects.filter(register_date__range=(start_date,end_date))
date:查具体哪一天内容
models.Account.objects.filter(register_date__date="2023-7-31")
models.Account.objects.filter(register_date__date__gt="2023-7-31") # 配合gt使用
year、month、day:查哪一年、哪一月份、哪一天
models.Account.objects.filter(register_date__year="2023")
models.Account.objects.filter(register_date__month="12")
models.Account.objects.filter(register_date__day="15")
week:查询一年的第几周(52)
week_day:查星期几,从1(星期日)到7(星期六)
models.Account.objects.filter(register_date__week_day=2) # 星期一
hour、mintue、second:查每天的哪小时、哪分钟、哪一秒
models.Account.objects.filter(register_date__hour=8)
models.Account.objects.filter(register_date__mintue=15)
models.Account.objects.filter(register_date__second=15)
regex:正则表达式
models.Account.objects.filter(password__regex=r"^(1)")
from django.shortcuts import render,HttpResponse
from django.db.models import Max,Min,Sum,Avg,Count
from app01.models import *
# Create your views here.
def add_person(request):
# 方式1
# p = PersonModel()
# try:
# p.name='xiaoM'
# p.age=21
# p.save()
# except Exception as e:
# return HttpResponse('add fail')
# return HttpResponse('add success!')
# 方式2
# try:
# p = PersonModel(name='xiaoK',age=22)
# p.save()
# except Exception as e:
# return HttpResponse('add fail')
# return HttpResponse('add success!')
# 方式3
try:
PersonModel.objects.create(name='ku',age=23)
except Exception as e:
return HttpResponse('add fail')
return HttpResponse('add success!')
def del_person(request):
try:
PersonModel.objects.filter(age__gt=20).delete()
except Exception as e:
return HttpResponse('delete fail')
return HttpResponse('delete success!')
def update_person(request):
try:
# p = PersonModel.objects.filter(age__gt=23).update(age=100)
p = PersonModel.objects.get(id=5)
p.age = 18
p.save()
except Exception as e:
print(e)
return HttpResponse('update fail')
return HttpResponse('update success!')
def get_person(request):
try:
# p = PersonModel.objects.get(id=5)
# print(p.name,p.age)
p = PersonModel.objects.all()
for o in p:
print(o.name,o.age)
except Exception as e:
print(e)
return HttpResponse('get fail')
return HttpResponse('get success!')
# 聚合函数
def aggregate(request):
p = PersonModel.objects.aggregate(Max('age'))
p = PersonModel.objects.aggregate(Min('age'))
p = PersonModel.objects.aggregate(Sum('age'))
p = PersonModel.objects.aggregate(Count('age'))
p = PersonModel.objects.aggregate(Avg('age'))
print(p)
# 排序
p = PersonModel.objects.all().order_by('age') # 升序
p = PersonModel.objects.all().order_by('age','id')
p = PersonModel.objects.all().order_by('-age') # 降序
print(p)
return HttpResponse('Success!')
1.关联分类
2.外键关联
from django.db import models
# 创建模型A
class ModelA(models.Model):
name = models.CharField(max_length=100)
# 创建模型B
class ModelB(models.Model):
name = models.CharField(max_length=100)
model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE) # 建立一对多关系
model_a = models.OneToOneField(ModelA, on_delete=models.CASCADE) # 建立一对一关联
# 注意:修改on_delete参数之后需要重新同步数据库
user_type = models.ForeignKey(UserType,on_delete=models.CASCADE)
models.CASCADE默认值(Django1.11) # 表示级联删除,即删除UserType时胡关联的User也会被删除
models.PROTECT # 保护模式,阻止级联删除。(若无外键关联可删除)
models.SET_NULL # 置空模式,设为null,nuLL=True参数必须具备
modeLs.SET_DEFAULT # 置默认值设为默认值,default参数必须具备
models.SET() # 删除的时候重新动态指向一个安体访问对应元素,可传两数
modeLs.DO_NOTHING什么也不做。(Django1.11) # 有外键约束
# 正向查询:直接调用关联的键查询
print(user.user_type.name)
print(user.user_type.id)
# 反向查询
# 内部自动生成 user_set 属性供反向查询
print(user_type.user_set.all()) # 返回QuerySet
print(user_type.user_set.filter(id=1))
# reLated_name:关联名称,设置反向查询的名称,原本使用user_set改为users
user_type = models.ForeignKey(UserType,,reLated_name=users)
print(user_type.users.all())
from django.db import models
# 创建模型A
class ModelA(models.Model):
name = models.CharField(max_length=100)
model_b = models.ForeignKey('ModelB', on_delete=models.CASCADE)
# 创建模型B
class ModelB(models.Model):
name = models.CharField(max_length=100)
model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
# 使用
m1 = ModelA.object.get(id=1)
m1.model_b.all()
m2 = ModelB.object.get(id=1)
m2.model_a.all()
all():返回所有数据
# models.py
class Account(models.Model):
"""账户表"""
username = models.CharField(max_length=64,unique=True)
email = models.EmailField(unique=True)
password = models.CharField(max_length=255)
register_date = models.DateTimeField(auto_now_add=True)
signature = models.CharField("签名",max_length=255,null=True)
# str方法在调用all方法时自动调用
def __str__(self):
return self.username
# python manage.py shell
modles.Account.objects.all() # 自动返回该类的初始化str方法
exclude():使用方法与filter()相同,结果与filter相反;排除符合条件的数据
models.Account.objects.exclude(register_date__date='2023-6-15')
values():将数据都封装成一个字典
a = models.Account.objects.all()
a.values()
# 通过键直接取该相应的值(字典)
a.values('username')
order_by():多字段排序
# 通过id进行顺序排序
a.values('id','register_date').order_by('id')
# 通过id进行逆序排序
a.values('id','register_date').order_by('id')
# 通过register_date进行顺序,若相同则根据id进行排序
a.values('id','register_date').order_by('register_date','id')
reverse():反转顺序,使用前必须先进行排序
a.values('id','register_date').reverse()
a.order_by('id').reverse()
get():精确查询一条数据(必须存在的数据),返回一个对象
a = models.Account.objects.get(id=1)
a = models.Account.objects.get(id__id=1) # 必须只存在一条大于1的数据
# 直接调用
a.username
o = models.Artilce.objects.all()[0]
o.title
o = models.Artilce.objects.all()[0]
o.account.username
a = models.Account.objects.get(name='job')
a.article_set.all()
a.article_set.select_related() # 使用效果与all相同
a = models.Article.objects.get(id=5)
a.tags.all()
a.tags.select_related() # 使用效果与all相同
t = models.Tag.objects.get(name='科技')
t.article_set.all()
a.article_set.select_related()
import datetime
from django.shortcuts import render,HttpResponse,redirect,reverse
from app01.models import *
# 获取cookie
def index(request):
# cookie
# 获取该页面的cookie为userid的值,若无则设为0
userid = request.COOKIES.get('userid',0)
# 获取登录的用户
user = userModel.objects.filter(id=userid).first()
return render(request,'index.html',{'user':user})
# 设置cookie
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
# 1、接收前端提交过来的数据
uname = request.POST.get('uname') # 参数为html的name属性值
passwd = request.POST.get('passwd')
# 2、登录验证
users = userModel.objects.filter(username=uname,password=passwd)
if users.exists():
# 获取当前登录的用户对象
user = users.first()
response = redirect(reverse('index'))
# 3、设置cookie
response.set_cookie('userid',user.id) # 创建cookie
# 设置过期时间
# response.set_cookie('userid',user.id,max_age=7*24*3600) # max_age:秒
# response.set_cookie('userid',user.id,
# expires=datetime.datetime(2023,9,5))
response.set_cookie('userid', user.id, # timedelta:时间差
expires=datetime.datetime.now()+datetime.timedelta(days=10))
# 跳转到登录页面
return response
return HttpResponse("当前账户不存在或账户密码有误,请重新输入或注册!")
# 删除cookie
def logout(request):
response = redirect(reverse('index'))
# 注销、删除cookie
response.delete_cookie('userid')
request.session.delete(session_key)
return response
import datetime
from django.shortcuts import render,HttpResponse,redirect,reverse
from app01.models import *
# 获取session
def index(request):
# session
userid = request.session.get('userid',0)
# 获取登录的用户
user = userModel.objects.filter(id=userid).first()
return render(request,'index.html',{'user':user})
# 设置session
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
# 1、接收前端提交过来的数据
uname = request.POST.get('uname') # 参数为html的name属性值
passwd = request.POST.get('passwd')
# 2、登录验证
users = userModel.objects.filter(username=uname,password=passwd)
if users.exists():
# 获取当前登录的用户对象
user = users.first()
response = redirect(reverse('index'))
# 3.设置session
request.session['userid'] = user.id
request.session.set_expiry(7*24*3600) # 设置过期时间
return response
return HttpResponse("当前账户不存在或账户密码有误,请重新输入或注册!")
# 删除session
def logout(request):
response = redirect(reverse('index'))
# 注销、删除session
session_key = request.session.session_key
request.session.delete(session_key)
return response
# 在项目的目录下执行
python manage.py createsuperuser
# app01/ admin.py
from app01 import models
admin.site.register(models.Account)
admin.site.register(models.Article)
admin.site.register(models.Tag)
# app01 --admin.py
# admin自定制
class AccountAdmin(admin.ModelAdmin):
list_display = ('username','email','register_date','signature') # 显示列表
search_fields = ('username','email') # 搜索内容
list_filter = ('register_date',) # 过滤
list_per_page = 5 #分页,每页几条数据
list_editable = ['signature',] # 可在列表修改的属性
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title','pub_date','account')
fields = ('title','content',('pub_date','tags'))# 可自定义显示范围
exclude = ('account',) # 与fields相反,不显示某字段
date_hierarchy = 'pub_date' # 按日期分类显示
fieldsets = (
('文章内容',
{'fields':('title','content'),
'classes':('wide','extrapretty'), # 样式
}
),
('发布相关',
{'fields':('account','pub_date'),
'classes':('collapse',), # 可折叠
}
)
)
# 只能针对多对多
# filter_vertical = ('tags',)
filter_horizontal = ('tags',)
radio_fields = {'account':admin.HORIZONTAL} # 由下拉框变单选框
autocomplete_fields = ['account',] # 外键自动补全,可用于查询数据
admin.site.register(models.Account,AccountAdmin) #模型与管理类相关联
admin.site.register(models.Article,ArticleAdmin)
admin.site.register(models.Tag)
class Account(models.Model):
"""账户表"""
signature = models.CharField("签名",max_length=255,null=True,blank=True) # blank与admin配合使用
# admin.py
class Article(models.Model):
def get_tags(self):
return ', '.join([i.name for i in self.tags.all()])
# admin.py
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title','pub_date','account','get_tags')
添加HTML样式
# models.py
from django.utils.html import format_html
class Tag(models.Model):
color_code = models.CharField(max_length=6)
def colored_name(self):
return format_html(
'{}',
self.color_code,
self.name,
)
# admin.py
class TagAdmin(admin.ModelAdmin):
list_display = ['name','colored_name']
自定义表单名称
# models.py
class Account(models.Model):
class Meta:
# verbose_name = '账户' # 存在复数形式
verbose_name_plural = '账户'
class Article(models.Model):
tags = models.ManyToManyField("Tag",verbose_name='标签')
class Meta:
verbose_name_plural = '文章'
class Tag(models.Model):
class Meta:
verbose_name_plural = '标签'
import sys
sys.path.append('..') # 返回上级目录