标签:django框架 complete counter 属性 项目文件 对应关系 day 校验器 price
http://www.luffycity.com:80/news/index.html?id=250&page=1
www.luffycity.com
,是服务器请求方式 url路径 协议版本\r\n
k1:v1\r\n
k2:v2\r\n
\r\n
数据
协议版本 状态码 状态码描述\r\n
k1:v1\r\n
k2:v2\r\n
\r\n
响应数据(响应体)
import socket
# 创建一个socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind((‘127.0.0.1‘, 8000))
# 监听
sk.listen(5)
# 等待连接
while True:
conn, addr = sk.accept()
# 接收数据
data= conn.recv(1024)
print(data)
# 返回数据
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>ok!</h1>‘)
# 断开连接
conn.close()
import socket
# 创建一个socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind((‘127.0.0.1‘, 8000))
# 监听
sk.listen(5)
# 等待连接
while True:
conn, addr = sk.accept()
# 接收数据
data = conn.recv(1024)
data = data.decode(‘utf-8‘)
url = data.split()[1]
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘)
if url == ‘/index/‘:
# 返回数据
conn.send(b‘<h1>index!</h1>‘)
elif url == ‘/home/‘:
conn.send(b‘<h1>home!</h1>‘)
else:
conn.send(b‘<h1>404 not found!</h1>‘)
# 断开连接
conn.close()
import socket
# 创建一个socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind((‘127.0.0.1‘, 8000))
# 监听
sk.listen(5)
# 函数
def index(url):
ret = ‘<h1>index!</h1>({})‘.format(url)
return ret.encode(‘utf-8‘)
def home(url):
ret = ‘<h1>home!</h1>({})‘.format(url)
return ret.encode(‘utf-8‘)
# 等待连接
while True:
conn, addr = sk.accept()
# 接收数据
data = conn.recv(1024)
data = data.decode(‘utf-8‘)
url = data.split()[1]
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘)
if url == ‘/index/‘:
# 返回数据
ret = index(url)
elif url == ‘/home/‘:
ret = home(url)
else:
ret = b‘<h1>404 not found!</h1>‘
conn.send(ret)
# 断开连接
conn.close()
import socket
# 创建一个socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind((‘127.0.0.1‘, 8000))
# 监听
sk.listen(5)
# 函数
def index(url):
ret = ‘<h1>index!</h1>({})‘.format(url)
return ret.encode(‘utf-8‘)
def home(url):
ret = ‘<h1>home!</h1>({})‘.format(url)
return ret.encode(‘utf-8‘)
# 定义一个list1和实际要执行的函数的对应关系
list1 = [
(‘/index/‘, index),
(‘/home/‘, home),
]
# 等待连接
while True:
conn, addr = sk.accept()
# 接收数据
data = conn.recv(1024)
data = data.decode(‘utf-8‘)
url = data.split()[1]
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘)
func = None
for i in list1:
if url == i[0]:
func = i[1]
break
if func:
ret = func(url)
else:
ret = b‘<h1>404 not found!</h1>‘
conn.send(ret)
# 断开连接
conn.close()
import socket
# 创建一个socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind((‘127.0.0.1‘, 8000))
# 监听
sk.listen(5)
# 函数
def index(url):
with open(‘index.html‘,‘rb‘) as f:
ret = f.read()
return ret
def home(url):
ret = ‘<h1>home!</h1>({})‘.format(url)
return ret.encode(‘utf-8‘)
# 定义一个list1和实际要执行的函数的对应关系
list1 = [
(‘/index/‘, index),
(‘/home/‘, home),
]
# 等待连接
while True:
conn, addr = sk.accept()
# 接收数据
data = conn.recv(1024)
data = data.decode(‘utf-8‘)
url = data.split()[1]
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘)
func = None
for i in list1:
if url == i[0]:
func = i[1]
break
if func:
ret = func(url)
else:
ret = b‘<h1>404 not found!</h1>‘
conn.send(ret)
# 断开连接
conn.close()
import socket
import time
# 创建一个socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind((‘127.0.0.1‘, 8000))
# 监听
sk.listen(5)
# 函数
def index(url):
with open(‘index.html‘, ‘rb‘) as f:
ret = f.read()
return ret
def home(url):
ret = ‘<h1>home!</h1>({})‘.format(url)
return ret.encode(‘utf-8‘)
def timer(url):
now = time.strftime(‘%H:%M:%S‘)
with open(‘time.html‘,‘r‘,encoding=‘utf-8‘) as f:
data = f.read()
data = data.replace(‘xxtimexx‘,now)
return data.encode(‘utf-8‘)
# 定义一个list1和实际要执行的函数的对应关系
list1 = [
(‘/index/‘, index),
(‘/home/‘, home),
(‘/time/‘, timer),
]
# 等待连接
while True:
conn, addr = sk.accept()
# 接收数据
data = conn.recv(1024)
data = data.decode(‘utf-8‘)
url = data.split()[1]
conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘)
func = None
for i in list1:
if url == i[0]:
func = i[1]
break
if func:
ret = func(url)
else:
ret = b‘<h1>404 not found!</h1>‘
conn.send(ret)
# 断开连接
conn.close()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>当前时间是:@@time@@</h1>
</body>
</html>
"""
根据URL中不同的路径返回不同的内容--函数进阶版
返回HTML页面
让网页动态起来
wsgiref模块版
"""
from wsgiref.simple_server import make_server
# 将返回不同的内容部分封装成函数
def index(url):
# 读取index.html页面的内容
with open("index.html", "r", encoding="utf8") as f:
s = f.read()
# 返回字节数据
return bytes(s, encoding="utf8")
def home(url):
with open("home.html", "r", encoding="utf8") as f:
s = f.read()
return bytes(s, encoding="utf8")
def timer(url):
import time
with open("time.html", "r", encoding="utf8") as f:
s = f.read()
s = s.replace(‘@@time@@‘, time.strftime("%Y-%m-%d %H:%M:%S"))
return bytes(s, encoding="utf8")
# 定义一个url和实际要执行的函数的对应关系
list1 = [
("/index/", index),
("/home/", home),
("/time/", timer),
]
def run_server(environ, start_response):
start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html;charset=utf8‘), ]) # 设置HTTP响应的状态码和头信息
url = environ[‘PATH_INFO‘] # 取到用户输入的url
func = None
for i in list1:
if i[0] == url:
func = i[1]
break
if func:
response = func(url)
else:
response = b"404 not found!"
return [response, ]
if __name__ == ‘__main__‘:
httpd = make_server(‘127.0.0.1‘, 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
from wsgiref.simple_server import make_server
from jinja2 import Template
def index(url):
# 读取HTML文件内容
with open("index2.html", "r", encoding="utf8") as f:
data = f.read()
template = Template(data) # 生成模板文件
ret = template.render({‘name‘: ‘alex‘, ‘hobby_list‘: [‘抽烟‘, ‘喝酒‘, ‘烫头‘]}) # 把数据填充到模板中
return bytes(ret, encoding="utf8")
def home(url):
with open("home.html", "r", encoding="utf8") as f:
s = f.read()
return bytes(s, encoding="utf8")
# 定义一个url和实际要执行的函数的对应关系
list1 = [
("/index/", index),
("/home/", home),
]
def run_server(environ, start_response):
start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html;charset=utf8‘), ]) # 设置HTTP响应的状态码和头信息
url = environ[‘PATH_INFO‘] # 取到用户输入的url
func = None
for i in list1:
if i[0] == url:
func = i[1]
break
if func:
response = func(url)
else:
response = b"404 not found!"
return [response, ]
if __name__ == ‘__main__‘:
httpd = make_server(‘127.0.0.1‘, 8090, run_server)
print("我在8090等你哦...")
httpd.serve_forever()
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>姓名:{{name}}</h1>
<h1>爱好:</h1>
<ul>
{% for hobby in hobby_list %}
<li>{{hobby}}</li>
{% endfor %}
</ul>
</body>
</html>
python36 manage.py runserver
—— 127.0.0.1:80`python36 manage.py runserver 80
——127.0.0.1:80python36 manage.py runserver 0.0.0.0:80
——0.0.0.0:80# 在urls.py中
# 导入
from django.shortcuts import HttpResponse,render
# 函数
def index(request):
# return HttpResponse(‘index‘)
return render(request,‘index.html‘)
# url和函数对应关系
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘^index/‘, index),
]
STATIC_URL = ‘/static/‘ # 别名
STATICFILES_DIRS = [ # 设置文件路径,可以设置多个
os.path.join(BASE_DIR, ‘static1‘),
os.path.join(BASE_DIR, ‘static‘),
os.path.join(BASE_DIR, ‘static2‘),
]
<link rel="stylesheet" href="/static/css/login.css"> {# 别名开头 #}
from django.shortcuts import redirect
# 在函数中使用,例如
return redirect(‘/index/‘) # 参数:路径url
# 注意:前面必须加/,代表从url根拼接,否则就会在当前url后面一直拼接
from django.shortcuts import HttpResponse, render, redirect
def index(request):
# return HttpResponse(‘index‘)
return render(request, ‘index.html‘)
def login(request):
if request.method == ‘POST‘:
# 获取form表单提交的书籍
username = request.POST[‘username‘]
password = request.POST[‘password‘]
# 验证用户名和密码
if models.User.objects.filter(username=username,password=password):
# 验证成功跳转到index页面
# return redirect(‘https://www.baidu.com/‘)
return redirect(‘/index/‘)
# 不成功 重新登录
return render(request, ‘login.html‘)
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘^index/‘, views.index),
url(r‘^login/‘, views.login),
]
INSTALLED_APPS = [
...
‘app01‘,
‘app01.apps.App01Config‘, # 推荐写法
]
DATABASES = {
‘default‘: {
‘ENGINE‘: ‘django.db.backends.mysql‘, # 引擎
‘NAME‘: ‘day53‘, # 数据库名称
‘HOST‘: ‘127.0.0.1‘, # ip地址
‘PORT‘:3306, # 端口
‘USER‘:‘root‘, # 用户
‘PASSWORD‘:‘123‘ # 密码
}
}
import pymysql
pymysql.install_as_MySQLdb()
from django.db import models
class User(models.Model):
username = models.CharField(max_length=32) # username varchar(32)
password = models.CharField(max_length=32) # username varchar(32)
USE_L10N = False
DATETIME_FORMAT = ‘Y-m-d H:i:s‘ # datetime类型
DATE_FORMAT = ‘Y-m-d‘ # date类型
TIME_FORMAT = ‘H:i:s‘ # time类型
value = "<a href=‘#‘>点我</a>"
from django import template
register = template.Library() # register也不能变
@register.filter
def add_xx(value, arg): # 最多有两个
return ‘{}-{}‘.format(value, arg)
@register.filter(name=‘adds‘) # 相当于更改了函数名,使用时,使用新的函数名
{% load my_tags %}
{{ ‘alex‘|add_xx:‘dsb‘ }}
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
Variable | Description |
---|---|
forloop.counter |
当前循环的索引值(从1开始) |
forloop.counter0 |
当前循环的索引值(从0开始) |
forloop.revcounter |
当前循环的倒序索引值(到1结束) |
forloop.revcounter0 |
当前循环的倒序索引值(到0结束) |
forloop.first |
当前循环是不是第一次循环(布尔值) |
forloop.last |
当前循环是不是最后一次循环(布尔值) |
forloop.parentloop |
本层循环的外层循环 |
{% for book in all_books %}
<tr>
.....
</tr>
{% empty %}
<td>没有相关的数据</td>
{% endfor %}
{% if 条件1 %}
xxx
{% elif 条件2 %}
xxx
{% else %}
xxxxx
{% endif %}
{% with hobby.2 as talk %}
{# 相当于 {% with talk=hobby.2 %},其中=两边不能有空格 #}
{{ talk }}
{% endwith %}
{# 要注释的内容 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
{% block page-css %}
{% endblock %}
</head>
<body>
<h1>这是母板的标题</h1>
{% block page-main %}
{% endblock %}
<h1>母板底部内容</h1>
{% block page-js %}
{% endblock %}
</body>
</html>
{% block 块名 %}
{% endblock %}
{% extends ‘layouts.html‘ %}
{% block page-main %}
<p>世情薄</p>
<p>人情恶</p>
<p>雨送黄昏花易落</p>
{% endblock %}
{% include ‘navbar.html‘ %}
{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi">
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}">
{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi">
{# 补充:获取别名 #}
{% get_static_prefix %}
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi">
@register.simple_tag
def join_str(*args, **kwargs):
return ‘{} - {} ‘.format(‘*‘.join(args), ‘$‘.join(kwargs.values()))
@register.simple_tag(name=‘join‘) # 相当于更改了函数名,使用时,使用新的函数名
{% load my_tags %}
{% join_str ‘1‘ ‘2‘ k1=‘3‘ k2=‘4‘ %}
from django import template
register = template.Library() # register也不能变
@register.inclusion_tag(‘result.html‘)
# result.html 是内容的html
def show_results(n):
n = 1 if n < 1 else int(n)
data = ["第{}项".format(i) for i in range(1, n+1)]
return {"data": data}
<ul>
{% for choice in data %}
<li>{{ choice }}</li>
{% endfor %}
</ul>
{% load my_inclusion %}
{% show_results 10 %}
from django import template
register = template.Library()
@register.filter(name=‘add_a‘)
def add_xx(value,arg):
return ‘addd_xx‘
@register.simple_tag
def join_str(*args,**kwargs):
return ‘xxxxx‘
@register.inslusion_tag(‘page.html‘)
def page(num):
return {‘num‘:range(1,num+1)}
{% for i in num %}
{{ i }}
{% endfor %}
{% load my_tags %}
{# filter#}
{{ ’xxx‘|add_xx:‘a‘ }} {{ ’xxx‘|add_a:‘a‘ }}
{# simple_tag #}
{% join_str 1 2 k1=3 k2=4 %}
{# inclusion_tag #}
{% page 4 %}
from django.views import View
class AddPublisher(View):
def get(self,request):
"""处理get请求"""
pass
def post(self,request):
"""处理post请求"""
pass
url(r‘^add_publisher/‘, views.AddPublisher.as_view())
def timer(func):
def inner(request, *args, **kwargs):
start = time.time()
ret = func(request, *args, **kwargs)
print("函数执行的时间是{}".format(time.time() - start))
return ret
return inner
@timer
def publisher_list(request):
pass
from django.utils.decorators import method_decorator
@method_decorator(timer)
def get(self, request, *args, **kwargs):
pass
@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
@method_decorator(timer,name=‘get‘)
class AddPublisher(View):
pass
@method_decorator(timer,name=‘dispatch‘)
class AddPublisher(View):
pass
url(r‘^upload/‘, views.upload)
def upload(request):
if request.method == ‘POST‘:
# 获取文件
# print(request.FILES)
f1 = request.FILES.get(‘f1‘)
# 保存文件
with open(f1.name, ‘wb‘) as f:
for i in f1.chunks():
f.write(i)
return render(request, ‘upload.html‘)
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="f1">
<button>上传</button>
</form>
from django.shortcuts import render, redirect, HttpResponse
HttpResponse(‘字符串‘) # 返回字符串
render(request,‘模板的文件名‘,{k1:v1}) # 返回一个完整的HTML页面
redirect(‘重定向的地址‘) # 返回重定向,Location:地址
import json
def json_data(request):
data = {‘name‘: ‘alex‘, ‘age‘: 73}
return HttpResponse(json.dumps(data))
# Content-Type: text/html; charset=utf-8
from django.http.response import JsonResponse
def json_data(request):
data = {‘name‘: ‘alex‘, ‘age‘: 73}
return JsonResponse(data)
# Content-Type: application/json
import json
def json_data(request):
data = {‘name‘: ‘alex‘, ‘age‘: 73}
return HttpResponse(json.dumps(data),content_type=‘application/json‘)
# 此时,Content-Type: application/json
from django.http.response import JsonResponse
def json_data(request):
data = [1, 2, 3, 4]
return JsonResponse(data,safe=False)
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图,参数,别名),
]
from django.urls import path,re_path
urlpatterns = [
path(‘articles/2003/‘, views.special_case_2003),
]
from django.conf.urls import url
from . import views
urlpatterns = [
url(r‘^articles/2003/$‘, views.special_case_2003),
]
from django.conf.urls import url
from . import views
urlpatterns = [
url(r‘^articles/([0-9]{4})/$‘, views.year_archive),
url(r‘^articles/([0-9]{4})/([0-9]{2})/$‘, views.month_archive),
]
from django.conf.urls import url
from . import views
urlpatterns = [
url(r‘^articles/(?P<year>[0-9]{4})/$‘, views.year_archive),
url(r‘^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$‘, views.month_archive),
]
http://www.example.com/myapp/
请求中,URLconf 将查找 /myapp/http://www.example.com/myapp/?page=3
请求中,URLconf 仍将查找 /myapp/# urls.py中
from django.conf.urls import url
from . import views
urlpatterns = [
url(r‘^blog/$‘, views.page),
url(r‘^blog/page(?P<num>[0-9]+)/$‘, views.page),
]
# 两个URL模式指向相同的view,但是第一个模式并没有从URL中捕获任何东西
# views.py中,可以为num指定默认值
def page(request, num="1"):
pass
# 如果第一个模式匹配上了,page函数将使用其默认参数num=“1”,如果第二个模式匹配,page将使用正则表达式捕获到的num值
from django.conf.urls import include, url
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘^app01/‘, include(‘app01.urls‘)), # 可以包含其他的URLconfs文件
]
from django.conf.urls import url
from . import views
urlpatterns = [
url(r‘^blog/$‘, views.blog),
url(r‘^blog/(?P<year>[0-9]{4})/(?P<month>\d{2})/$‘, views.blogs),
]
from django.conf.urls import include, url
urlpatterns = [
url(r‘^app01/‘, include(‘app01.urls‘, namespace=‘app01‘)),
url(r‘^app02/‘, include(‘app02.urls‘, namespace=‘app02‘)),
]
from django.conf.urls import url
urlpatterns = [
url(r‘^home‘, views.home, name=‘home‘), # 给我的url匹配模式起名为 home
url(r‘^index/(\d*)‘, views.index, name=‘index‘), # 给我的url匹配模式起名为index
]
from django.conf.urls import url
urlpatterns = [
url(r‘^blog/$‘, views.blog, name=‘blog‘),
]
{% url ‘blog‘ %} {# 完整URL路径:/blog/ #}
from django.urls import reverse
reverse(‘blog‘) # 完整URL路径:/blog/
from django.conf.urls import url
urlpatterns = [
url(r‘^blog/([0-9]{4})/(\d{2})/$‘, views.blogs, name=‘blogs‘),
]
{% url ‘blogs‘ 2222 12 %} {# 完整URL路径:/blog/2222/12/ #}
from django.urls import reverse
reverse(‘blogs‘,args=(‘2019‘,‘06‘)) # 完整URL路径:/blog/2019/06/
from django.conf.urls import url
urlpatterns = [
url(r‘^blog/(?P<year>[0-9]{4})/(?P<month>\d{2})$‘, views.blogs, name=‘blogs‘),
]
{% url ‘blogs‘ year=2222 month=12 %} {# 完整URL路径:/blog/2222/12/ #}
from django.urls import reverse
reverse(‘blogs‘,kwargs={‘year‘:‘2019‘,‘month‘:‘06‘}) # 完整URL路径:/blog/2019/06/
from django.conf.urls import url, include
urlpatterns = [
url(r‘^app01/‘, include(‘app01.urls‘, namespace=‘app01‘)),
url(r‘^app02/‘, include(‘app02.urls‘, namespace=‘app02‘)),
]
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r‘^(?P<pk>\d+)/$‘, views.detail, name=‘detail‘)
]
from django.conf.urls import url
from app02 import views
urlpatterns = [
url(r‘^(?P<pk>\d+)/$‘, views.detail, name=‘detail‘)
]
{% url ‘app01:detail‘ pk=12 %}
{% url ‘app02:detail‘ pk=12 %}
from django.urls import reverse
reverse(‘app01:detail‘, kwargs={‘pk‘:11})
reverse(‘app01:detail‘, kwargs={‘pk‘:11})
{# 简单示例:app01是第一层路由空间的namespace,xxx是第二层路由空间的namespace #}
{% url ‘app01:xxx:index‘ %}
ORM | DB |
---|---|
类 | 数据表 |
对象 | 数据行 |
属性 | 字段 |
YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
,相当于Python中的datetime.datetime的实例class MyCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return ‘char(%s)‘ % self.max_length
class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=25)
# 使用自定义的char类型的字段
cname = MyCharField(max_length=25)
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32)
class Meta:
# 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
db_table = "table_name"
# admin中显示的表名称
verbose_name = ‘个人信息‘
# verbose_name加s
verbose_name_plural = ‘所有用户信息‘
# 联合索引
index_together = [
("pub_date", "deadline"), # 应为两个存在的字段
]
# 联合唯一索引
unique_together = (("driver", "restaurant"),) # 应为两个存在的字段
# 返回的是queryset对象的
all()
filter()
exclude()
values()
values_list()
order_by()
reverse()
distinct()
# 返回的是单个对象的
get()
first()
last()
# 返回的是数字的
count()
# 返回的是布尔值的
exists()
book_obj = models.Book.objects.get(title=‘菊花怪大战MJJ‘)
book_obj.pub
book_obj.pub.name
pub_obj = models.Publisher.objects.get(pk=1)
# 没有指定related_name,使用类名小写_set
pub_obj.book_set.all()
# 指定related_name=‘books‘
pub_obj.books.all()
# 查询老男孩出版的书
ret = models.Book.objects.filter(pub__name=‘老男孩出版社‘)
# 查询出版菊花怪大战MJJ的出版社
# 没有指定related_name,使用类名的小写
ret= models.Publisher.objects.filter(book__title=‘菊花怪大战MJJ‘)
# related_name=‘books‘
ret= models.Publisher.objects.filter(books__title=‘菊花怪大战MJJ‘)
# related_query_name=‘xxx‘
ret= models.Publisher.objects.filter(xxx__title=‘菊花怪大战MJJ‘)
mjj = models.Author.objects.get(pk=1)
mjj.books # 关系管理对象
mjj.books.all()
book_obj = models.Book.objects.filter(title=‘桃花侠大战菊花怪‘).first()
# 不指定related_name
book_obj.author_set # 关系管理对象
book_obj.author_set.all()
# 指定related_name=‘authors‘
book_obj.authors # 关系管理对象
book_obj.authors.all()
ret = models.Author.objects.filter(books__title=‘菊花怪大战MJJ‘)
# 不指定related_name
ret = models.Book.objects.filter(author__name=‘MJJ‘)
# 指定related_name=‘authors‘
ret = models.Book.objects.filter(authors__name=‘MJJ‘)
# 指定related_query_name=‘xxx‘
ret = models.Book.objects.filter(xxx__name=‘MJJ‘)
mjj = models.Author.objects.get(pk=1)
mjj.books.all()
# set() [id,id] [对象,对象]
mjj.books.set([1,2])
mjj.books.set(models.Book.objects.filter(pk__in=[1,2,3]))
# add (id,id) (对象,对象)
mjj.books.add(4,5)
mjj.books.add(*models.Book.objects.filter(pk__in=[4,5]))
# remove (id,id) (对象,对象)
mjj.books.remove(4,5)
mjj.books.remove(*models.Book.objects.filter(pk__in=[4,5]))
mjj.books.clear()
obj = mjj.books.create(title=‘跟MJJ学前端‘,pub_id=1)
book__obj = models.Book.objects.get(pk=1)
obj = book__obj.authors.create(name=‘taibai‘)
from app01 import models
from django.db.models import Max, Min, Avg, Sum, Count
# 为聚合值指定名称,注意关键字传参要在位置传参后面
ret = models.Book.objects.filter(pk__gt=3).aggregate(Max(‘price‘),avg=Avg(‘price‘))
print(ret)
# 统计每一本书的作者个数,annotate:注释
ret = models.Book.objects.annotate(count=Count(‘author‘))
# 统计出每个出版社的最便宜的书的价格
# 方式一
ret = models.Publisher.objects.annotate(Min(‘book__price‘)).values()
# 方式二:objects后面接values,就是按字段分组,相当于分组条件
ret = models.Book.objects.values(‘pub_id‘).annotate(min=Min(‘price‘))
from django.db.models import F
# 比较两个字段的值
ret=models.Book.objects.filter(sale__gt=F(‘kucun‘))
# 只更新sale字段
models.Book.objects.all().update(sale=100)
# 取某个字段的值进行操作
models.Book.objects.all().update(sale=F(‘sale‘)*2+10)
from django.db.models import Q
ret = models.Book.objects.filter(~Q(Q(pk__gt=3) | Q(pk__lt=2)) & Q(price__gt=50))
print(ret)
from django.db import transaction
try:
with transaction.atomic():
# 进行一系列的ORM操作
models.Publisher.objects.create(name=‘xxxxx‘)
models.Publisher.objects.create(name=‘xxx22‘)
except Exception as e :
print(e)
# 执行原生SQL
# 更高灵活度的方式执行原生SQL语句
from django.db import connection, connections
cursor = connection.cursor()
cursor = connections[‘default‘].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone()
LOGGING = {
‘version‘: 1,
‘disable_existing_loggers‘: False,
‘handlers‘: {
‘console‘:{
‘level‘:‘DEBUG‘,
‘class‘:‘logging.StreamHandler‘,
},
},
‘loggers‘: {
‘django.db.backends‘: {
‘handlers‘: [‘console‘],
‘propagate‘: True,
‘level‘:‘DEBUG‘,
},
}
}
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
# orm_practice.settings表示当前项目的settings.py,orm_practice是当前项目名称
import django
django.setup()
from app01 import models
# 再继续写要执行的语句,例如
books = models.Book.objects.all()
print(books)
# HttpResponse,render也可以
ret = redirect(‘/index‘)
ret.set_cookie(‘key‘,value,...) # Set-Cookie:key=value
ret.set_signed_cookie(‘key‘,value,salt=‘加密盐‘,...)
request.COOKIES.get(‘key‘)
request.get_signed_cookie(‘key‘,salt=‘加密盐‘,default=RAISE_ERROR,max_age=None)
def logout(request):
ret = redirect("/login/")
ret.delete_cookie("key") # 删除用户浏览器上之前设置的cookie值
return rep
from django.shortcuts import render, redirect, HttpResponse
from django.views import View
class Login(View):
def get(self, request, *args, **kwargs):
return render(request, ‘login.html‘)
def post(self, request, *args, **kwargs):
username = request.POST.get(‘username‘)
pwd = request.POST.get(‘pwd‘)
if username == ‘alex‘ and pwd == ‘123‘:
url = request.GET.get(‘return_url‘)
if url:
ret = redirect(url)
else:
ret = redirect(‘/index/‘)
# 设置 cookie
# ret[‘Set-Cookie‘] = ‘is_login=100; Path=/‘
ret.set_cookie(‘is_login‘, ‘1‘) # 不加密的 Set-Cookie: is_login=1; Path=/
ret.set_signed_cookie(‘is_login‘, ‘1‘, ‘s21‘,max_age=10000,) # 加密的
return ret
return render(request, ‘login.html‘, {‘error‘: ‘用户名或密码错误‘})
# 登录验证装饰器
def login_required(func):
def inner(request, *args, **kwargs):
# 获取 cookie
is_login = request.COOKIES.get(‘is_login‘) # 不加密的
is_login = request.get_signed_cookie(‘is_login‘, salt=‘s21‘, default=‘‘) # 加密的
print(is_login)
url = request.path_info
if is_login != ‘1‘:
return redirect(‘/login/?return_url={}‘.format(url))
# 已经登录
ret = func(request, *args, **kwargs)
return ret
return inner
# 在需要在需要登录才能访问到页面的视图上加装饰器
@login_required
def index(request):
return HttpResponse(‘首页‘)
@login_required
def home(request):
return HttpResponse(‘home‘)
def logout(request):
ret = redirect(‘/login/‘)
ret.delete_cookie(‘is_login‘)
return ret
request.session[‘key‘] = value
request.session.setdefault(‘key‘,value) # 设置默认值,存在则不设置
request.session[‘key‘]
request.session.get(‘key‘,None)
del request.session[‘key‘]
# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
# 会话session的key
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查会话session的key在数据库中是否存在
request.session.exists("session_key")
# 删除当前会话的所有Session数据
request.session.delete()
# 删除当前的会话数据并删除会话的Cookie
request.session.flush()
# 这用于确保前面的会话数据不可以再次被用户的浏览器访问
# 例如,django.contrib.auth.logout() 函数中就会调用它
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
# 如果value是个整数,session会在些秒数后失效
# 如果value是个datatime或timedelta,session就会在这个时间后失效
# 如果value是0,用户关闭浏览器session就会失效
# 如果value是None,session会依赖全局session失效策略
from django.shortcuts import render, redirect, HttpResponse
from django.views import View
class Login(View):
def get(self, request, *args, **kwargs):
return render(request, ‘login.html‘)
def post(self, request, *args, **kwargs):
username = request.POST.get(‘username‘)
pwd = request.POST.get(‘pwd‘)
if username == ‘alex‘ and pwd == ‘123‘:
url = request.GET.get(‘return_url‘)
if url:
ret = redirect(url)
else:
ret = redirect(‘/index/‘)
# 设置 session
request.session[‘is_login‘] = 1 # value可以设置为数字
# 设置会话Session和Cookie的超时时间,0表示用户关闭浏览器session就会失效
# request.session.set_expiry(0)
return ret
return render(request, ‘login.html‘, {‘error‘: ‘用户名或密码错误‘})
# 登录验证装饰器
def login_required(func):
def inner(request, *args, **kwargs):
# 获取 session
is_login = request.session.get(‘is_login‘)
print(is_login)
url = request.path_info
if is_login != 1:
return redirect(‘/login/?return_url={}‘.format(url))
# 已经登录
ret = func(request, *args, **kwargs)
return ret
return inner
# 在需要在需要登录才能访问到页面的视图上加装饰器
@login_required
def index(request):
# request.session.session_key:会话session的key
request.session.clear_expired() # 将失效的数据删除
return HttpResponse(‘首页‘)
@login_required
def home(request):
return HttpResponse(‘home‘)
def logout(request):
ret = redirect(‘/login/‘)
request.session.delete() # 删除session数据 不删除cookie
request.session.flush() # 删除session数据 并删除cookie
return ret
1. 数据库Session
SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 引擎(默认)
2. 缓存Session
SESSION_ENGINE = ‘django.contrib.sessions.backends.cache‘ # 引擎
# 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
SESSION_CACHE_ALIAS = ‘default‘
3. 文件Session
SESSION_ENGINE = ‘django.contrib.sessions.backends.file‘ # 引擎
# 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
SESSION_FILE_PATH = None
4. 缓存+数据库
SESSION_ENGINE = ‘django.contrib.sessions.backends.cached_db‘ # 引擎
5. 加密Cookie Session
SESSION_ENGINE = ‘django.contrib.sessions.backends.signed_cookies‘ # 引擎
其他公用设置项:
# Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_NAME = "sessionid"
# Session的cookie保存的路径(默认)
SESSION_COOKIE_PATH = "/"
# Session的cookie保存的域名(默认)
SESSION_COOKIE_DOMAIN = None
# 是否Https传输cookie(默认)
SESSION_COOKIE_SECURE = False
# 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_HTTPONLY = True
# Session的cookie失效日期(2周)(默认)
SESSION_COOKIE_AGE = 1209600
# 是否关闭浏览器使得Session过期(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# 是否每次请求都保存Session,默认修改之后才保存(默认)
SESSION_SAVE_EVERY_REQUEST = False
# urls.py
urlpatterns = [
url(r‘^ajax_add/‘, views.ajax_add),
url(r‘^ajax_demo1/‘, views.ajax_demo1),
]
# views.py
def ajax_demo1(request):
return render(request, "ajax_demo1.html")
def ajax_add(request):
i1 = int(request.GET.get("i1"))
i2 = int(request.GET.get("i2"))
ret = i1 + i2
return JsonResponse(ret, safe=False)
{# ajax_demo1.html #}
<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">
<script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/",
type:"GET",
data:{"i1":$("#i1").val(),"i2":$("#i2").val()},
success:function (data) {
$("#i3").val(data);
},
error:function (error) {
console.log(error)
},
})
})
</script>
# views.py
def ajax_test(request):
user_name = request.POST.get("username")
password = request.POST.get("password")
print(user_name, password)
return HttpResponse("OK")
<button id="ajaxTest">AJAX 测试</button>
<script>
$("#ajaxTest").click(function () {
$.ajax({
url: "/ajax_test/",
type: "POST",
data: {username: "Q1mi", password: 123456},
success: function (data) {
alert(data)
}
})
})
</script>
<script>
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/",
type:"GET",
data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},
success:function (data) {
$("#i3").val(data);
}
})
})
</script>
$.ajax({
url: "/cookie_ajax/",
type: "POST",
data: {
"username": "Q1mi",
"password": 123456,
{# 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中 #}
"csrfmiddlewaretoken": $("[name = ‘csrfmiddlewaretoken‘]").val()
},
success: function (data) {
console.log(data);
}
})
$.ajax({
url: "/cookie_ajax/",
type: "POST",
{# 从Cookie取csrftoken,并设置到请求头中 #}
headers: {"X-CSRFToken": $("[name = ‘csrfmiddlewaretoken‘]").val()},
data: {"username": "Q1mi", "password": 123456},
success: function (data) {
console.log(data);
}
})
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== ‘‘) {
var cookies = document.cookie.split(‘;‘);
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) === (name + ‘=‘)) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// 通过js获取csrftoken的值
var csrftoken = getCookie(‘csrftoken‘);
// 使用$.ajaxSetup()方法为ajax请求统一设置
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
// 不是 GET|HEAD|OPTIONS|TRACE 这些请求的话,就执行if后的操作
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken); // 设置请求头,本质同方法2
}
}
});
<input type="file" id="f1">
<button id="b1">上传</button>
<script src="/static/jquery.js"></script>
<script>
$(‘#b1‘).click(function () {
var formobj = new FormData();
formobj.append(‘file‘,$(‘#f1‘)[0].files[0]);
formobj.append(‘name‘,‘alex‘);
$.ajax({
url: ‘/upload/‘,
type: ‘post‘,
data:formobj ,
processData:false,
contentType:false,
success: function (res) {
$("[name=‘i3‘]").val(res)
},
})
})
</script>
from django import forms
# 按照Django form组件的要求自己写一个类
class RegForm(forms.Form):
name = forms.CharField(label="用户名")
pwd = forms.CharField(label="密码")
# 使用form组件实现注册方式
def register2(request):
form_obj = RegForm()
if request.method == "POST":
# 实例化form对象的时候,把post提交过来的数据直接传进去
form_obj = RegForm(request.POST)
# 调用form_obj校验数据的方法
if form_obj.is_valid(): # 对数据进行校验
# form_obj.cleaned_data:通过校验的数据
return HttpResponse("注册成功")
return render(request, "register2.html", {"form_obj": form_bj})
<form action="/reg2/" method="post" novalidate autocomplete="off">
{% csrf_token %}
<div>
<label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
{{ form_obj.name }} {{ form_obj.name.errors.0 }}
</div>
<div>
<label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
{{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
</div>
<div>
<input type="submit" class="btn btn-success" value="注册">
</div>
</form>
{{ form_obj.as_p }}:生成一个个P标签 input label
{{ form_obj.errors }}:form表单中所有字段的错误
{{ form_obj.username }}:一个字段对应的input框
{{ form_obj.username.label }}:该字段的中文提示
{{ form_obj.username.id_for_label }}:该字段input框的id
{{ form_obj.username.errors }}:该字段的所有的错误
{{ form_obj.username.errors.0 }}:该字段的第一个错误
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三" # 设置默认值
)
pwd = forms.CharField(min_length=6, label="密码")
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
class LoginForm(forms.Form):
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.PasswordInput
)
class LoginForm(forms.Form):
gender = forms.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.RadioSelect
)
class LoginForm(forms.Form):
hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=3,
widget=forms.Select
)
class LoginForm(forms.Form):
hobby = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=[1, 3],
widget=forms.SelectMultiple
)
class LoginForm(forms.Form):
keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.CheckboxInput
)
class LoginForm(forms.Form):
hobby = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.CheckboxSelectMultiple
)
from django.forms import Form
from django.forms import widgets
from django.forms import fields
class MyForm(Form):
user = fields.ChoiceField(
# choices=((1, ‘上海‘), (2, ‘北京‘),),
initial=2,
widget=widgets.Select
)
def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs)
# self.fields[‘user‘].choices = ((1, ‘上海‘), (2, ‘北京‘),)或
self.fields[‘user‘].choices = models.Classes.objects.all().values_list(‘id‘,‘caption‘)
from django import forms
from django.forms import fields
from django.forms import models as form_model
class FInfo(forms.Form):
# 多选
authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())
# 单选
authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
Field
required=True, # 是否允许为空
widget=None, # HTML插件
label=None, # 用于生成Label标签或显示内容
initial=None, # 初始值
help_text=‘‘, # 帮助信息(在标签旁边显示)
error_messages=None, # 错误信息 {‘required‘: ‘不能为空‘, ‘invalid‘: ‘格式错误‘}
validators=[], # 自定义验证规则
localize=False, # 是否支持本地化
disabled=False, # 是否可以编辑
label_suffix=None # Label内容后缀
CharField(Field)
max_length=None, # 最大长度
min_length=None, # 最小长度
strip=True # 是否移除用户输入空白
IntegerField(Field)
max_value=None, # 最大值
min_value=None, # 最小值
ChoiceField(Field)
choices=(), # 选项,如:choices = ((0,‘上海‘),(1,‘北京‘),)
required=True, # 是否必填
widget=None, # 插件,默认select插件
label=None, # Label内容
initial=None, # 初始值
help_text=‘‘, # 帮助提示
ModelChoiceField(ChoiceField)
queryset, # 查询数据库中的数据
empty_label="---------", # 默认空显示内容
to_field_name=None, # HTML中value的值对应的字段
limit_choices_to=None # ModelForm中对queryset二次筛选
ModelMultipleChoiceField(ModelChoiceField)
from django.core.exceptions import ValidationError
def checkname(value):
# 通过校验规则 不做任何操作
# 不通过校验规则 抛出异常
if ‘alex‘ in value:
raise ValidationError(‘不符合社会主义核心价值观‘)
from django import forms
from django.core.validators import RegexValidator
class RegForm(forms.Form):
phone = forms.CharField(
validators=[RegexValidator(r‘^1[3-9]\d{9}$‘, ‘手机号格式不正确‘)]
)
def clean_username(self):
# 局部钩子
# 通过校验规则 必须返回当前字段的值
# 不通过校验规则 抛出异常
v = self.cleaned_data.get(‘username‘)
if ‘alex‘ in v:
raise ValidationError(‘不符合社会主义核心价值观‘)
else:
return v # 必须返回当前字段的值
def clean(self):
# 全局钩子
# 通过校验规则 必须返回所有所有字段的值
# 不通过校验规则 抛出异常 ‘__all__‘
pwd = self.cleaned_data.get(‘pwd‘)
re_pwd = self.cleaned_data.get(‘re_pwd‘)
if pwd == re_pwd:
return self.cleaned_data # 必须返回所有所有字段的值
else:
self.add_error(‘re_pwd‘,‘两次密码不一致!!!!!‘) # 在字段‘re_pwd‘后显示错误信息
raise ValidationError(‘两次密码不一致‘) # 在‘__all__‘中显示错误信息
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.views.decorators.csrf import csrf_exempt,csrf_protect,ensure_csrf_cookie
csrf_exempt # 某个视图不需要进行csrf校验,只能加在dispatch方法上
csrf_protect # 某个视图需要进行csrf校验
ensure_csrf_cookie # 确保生成csrf的cookie
MIDDLEWARE的‘django.middleware.csrf.CsrfViewMiddleware‘注释掉
DATABASES = {
‘default‘: {
‘ENGINE‘: ‘django.db.backends.mysql‘,
‘NAME‘: ‘bookmanager‘,
‘HOST‘: ‘127.0.0.1‘,
‘PORT‘: 3306,
‘USER‘: ‘root‘,
‘PASSWORD‘: ‘123‘,
}
}
import pymysql
pymysql.install_as_MySQLdb()
from django.db import models
class Publisher(models.Model):
# 设置pid为主键
pid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32,unique=True)
# 检测每个注册app下的model.py,记录model的变更记录
python manage.py makemigrations
# 同步变更记录到数据库中
python manage.py migrate
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
# 展示功能
url(r‘^publisher_list/‘, views.publisher_list),
# 新增功能
url(r‘^add_publisher/‘, views.add_publisher),
# 删除功能
url(r‘^del_publisher/‘, views.del_publisher),
# 编辑功能
url(r‘^edit_publisher/‘, views.edit_publisher),
]
from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# 展示出版社
def publisher_list(request):
# 从数据库中查询到出版社的信息
all_publishers = models.Publisher.objects.all().order_by(‘pk‘)
# 返回一个包含出版社信息的页面
return render(request, ‘publisher_list.html‘, {‘all_publishers‘: all_publishers})
<h1>出版社列表</h1>
<a href="/add_publisher/">新增</a>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{# 使用for循环获取数据,完善表格 #}
{% for publisher in all_publishers %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ publisher.pk }}</td>
<td>{{ publisher.name }}</td>
<td>
<a href="/del_publisher/?id={{ publisher.pk }}">删除</a>
<a href="/edit_publisher/?id={{ publisher.pk }}">编辑</a>
</td>
</tr>
{% endfor %} <!--for循环必须要以endfor结束-->
</tbody>
</table>
# 新增出版社
def add_publisher(request):
error = ‘‘
# 对请求方式进行判断
if request.method == ‘POST‘:
# 处理POST请求
# 获取到出版社的名称
publisher_name = request.POST.get(‘publisher_name‘)
# 判断出版社名称是否有重复的
if models.Publisher.objects.filter(name=publisher_name):
error = ‘出版社名称已存在‘
# 判断输入的值是否为空
if not publisher_name:
error = ‘不能输入为空‘
if not error:
# 使用ORM将数据插入到数据库中
obj = models.Publisher.objects.create(name=publisher_name)
# 跳转到展示出版社的页面
return redirect(‘/publisher_list/‘)
# 返回一个包含form表单的页面
return render(request, ‘add_publisher.html‘, {‘error‘: error})
<form action="" method="post">
<p> 出版社名称:
<input type="text" name="publisher_name">{{ error }}
</p>
<button>提交</button>
</form>
# 删除出版社
def del_publisher(request):
# 获取要删除的数据
pk = request.GET.get(‘id‘)
obj_list = models.Publisher.objects.filter(pk=pk)
if not obj_list:
# 没有要删除的数据
return HttpResponse(‘要删除的数据不存在‘)
# 删除该数据
# obj.delete()
obj_list.delete()
# 跳转到展示页面
return redirect(‘/publisher_list/‘)
# 编辑出版社
def edit_publisher(request):
error = ‘‘
# 查找要编辑的数据
pk = request.GET.get(‘id‘) # url上携带的参数 不是GET请求提交参数
obj_list = models.Publisher.objects.filter(pk=pk)
if not obj_list:
return HttpResponse(‘要编辑的数据不存在‘)
obj = obj_list[0]
if request.method == ‘POST‘:
# 处理POST请求
# 获取新提交的出版的名称
publisher_name = request.POST.get(‘publisher_name‘)
if models.Publisher.objects.filter(name=publisher_name):
# 新修改的名称已存在
error = ‘新修改的名称已存在‘
if obj.name == publisher_name:
error = ‘名称未修改‘
if not publisher_name:
error = ‘名称不能为空‘
if not error:
# 修改数据
obj.name = publisher_name
obj.save() # 保存数据到数据库中
# 跳转到出版社的展示页面
return redirect(‘/publisher_list/‘)
# 返回一个包含原始数据的页面
return render(request, ‘edit_publisher.html‘, {‘obj‘: obj,‘error‘:error})
<form action="" method="post">
<p> 出版社名称:
<input type="text" name="publisher_name" value="{{ obj.name }}"> {{ error }}
</p>
<button>提交</button>
</form>
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
pub = models.ForeignKey(‘Publisher‘, on_delete=models.CASCADE)
# 检测每个注册app下的model.py,记录model的变更记录
python manage.py makemigrations
# 同步变更记录到数据库中
python manage.py migrate
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘^publisher_list/‘, views.publisher_list),
url(r‘^add_publisher/‘, views.add_publisher),
url(r‘^del_publisher/‘, views.del_publisher),
url(r‘^edit_publisher/‘, views.edit_publisher),
url(r‘^book_list/‘, views.book_list),
url(r‘^add_book/‘, views.add_book),
url(r‘^del_book/‘, views.del_book),
url(r‘^edit_book/‘, views.edit_book),
]
from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# 展示书籍
def book_list(request):
# 查询所有的书籍
all_books = models.Book.objects.all()
return render(request, ‘book_list.html‘, {‘all_books‘: all_books})
<a href="/add_book/" target="_blank">添加</a>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>ID</th>
<th>书名</th>
<th>出版社名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book in all_books %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.pk }}</td>
<td>{{ book.title }}</td>
<td>{{ book.pub }}</td>
<td>
<a href="/del_book/?id={{ book.pk }}">删除</a>
<a href="/edit_book/?id={{ book.pk }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
all_books = models.Book.objects.all()
for book in all_books:
print(book.title)
print(book.pub,type(book.pub)) # ——> 所关联的出版社对象
print(book.pub.pk) # 查id 多一次查询
print(book.pub_id) # 直接在book表中查出的ID
print(book.pub.name)
# 添加书籍
def add_book(request):
if request.method == ‘POST‘:
# 获取数据
book_name = request.POST.get(‘book_name‘)
pub_id = request.POST.get(‘pub_id‘)
# 将数据插入到数据库
# models.Book.objects.create(title=book_name,pub=models.Publisher.objects.get(pk=pub_id))
models.Book.objects.create(title=book_name, pub_id=pub_id)
# 跳转到书籍的展示页面
return redirect(‘/book_list/‘)
# all_books = models.Book.objects.all()
# return render(request, ‘book_list.html‘, {‘all_books‘: all_books})
# 查询所有的出版社
all_publishers = models.Publisher.objects.all()
return render(request, ‘add_book.html‘, {‘all_publishers‘: all_publishers})
<form action="" method="post">
<p>书名: <input type="text" name="book_name"></p>
<p>出版社:
<select name="pub_id" id="">
{% for publisher in all_publishers %}
<option value="{{ publisher.pk }}"> {{ publisher.name }} </option>
{% endfor %}
</select>
</p>
<button>新增</button>
</form>
# 删除书籍
def del_book(request):
# 获取要删除的对象删除
pk = request.GET.get(‘id‘)
models.Book.objects.filter(pk=pk).delete()
# 跳转到展示页面
return redirect(‘/book_list/‘)
# 编辑书籍
def edit_book(request):
# 获取要编辑的书籍对象
pk = request.GET.get(‘id‘)
book_obj = models.Book.objects.get(pk=pk)
if request.method == ‘POST‘:
# 获取提交的数据
book_name = request.POST.get(‘book_name‘)
pub_id = request.POST.get(‘pub_id‘)
# 修改数据
book_obj.title = book_name
# book_obj.pub_id = pub_id
book_obj.pub = models.Publisher.objects.get(pk=pub_id)
book_obj.save()
# 重定向到展示页面
return redirect(‘/book_list/‘)
# 查询所有的出版社
all_publishers = models.Publisher.objects.all()
return render(request, ‘edit_book.html‘, {‘book_obj‘: book_obj, ‘all_publishers‘: all_publishers})
<form action="" method="post">
<p>书名: <input type="text" name="book_name" value="{{ book_obj.title }}"></p>
<p>出版社:
<select name="pub_id" id="">
{% for publisher in all_publishers %}
{% if book_obj.pub == publisher %}
<option selected value="{{ publisher.pk }}"> {{ publisher.name }} </option>
{% else %}
<option value="{{ publisher.pk }}"> {{ publisher.name }} </option>
{% endif %}
{% endfor %}
</select>
</p>
<button>保存</button>
</form>
# 修改数据
book_obj.title = book_name
# book_obj.pub_id = pub_id
book_obj.pub = models.Publisher.objects.get(pk=pub_id)
book_obj.save()
{% if book_obj.pub == publisher %}
<option selected value="{{ publisher.pk }}"> {{ publisher.name }} </option>
{% else %}
<option value="{{ publisher.pk }}"> {{ publisher.name }} </option>
{% endif %}
from django.db import models
# 会自动生成第三张表
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField(‘Book‘) # 不在Author表中生产字段,生产第三张表
# 检测每个注册app下的model.py,记录model的变更记录
python manage.py makemigrations
# 同步变更记录到数据库中
python manage.py migrate
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘^publisher_list/‘, views.publisher_list),
url(r‘^add_publisher/‘, views.add_publisher),
url(r‘^del_publisher/‘, views.del_publisher),
url(r‘^edit_publisher/‘, views.edit_publisher),
url(r‘^book_list/‘, views.book_list),
url(r‘^add_book/‘, views.add_book),
url(r‘^del_book/‘, views.del_book),
url(r‘^edit_book/‘, views.edit_book),
url(r‘^author_list/‘, views.author_list),
url(r‘^add_author/‘, views.add_author),
url(r‘^del_author/‘, views.del_author),
url(r‘^edit_author/‘, views.edit_author),
]
from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# 展示作者
def author_list(request):
# 查询所有的作者
all_authors = models.Author.objects.all()
return render(request, ‘author_list.html‘, {‘all_authors‘: all_authors})
<a href="/add_author/" target="_blank">添加</a>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>id</th>
<th>姓名</th>
<th>代表作</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for author in all_authors %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ author.pk }}</td>
<td>{{ author.name }}</td>
<td>
{% for book in author.books.all %}
{% if forloop.last %}
《{{ book.title }}》
{% else %}
《{{ book.title }}》、
{% endif %}
{% endfor %}
</td>
<td>
<a href="/del_author/?pk={{ author.pk }}">删除</a>
<a href="/edit_author/?pk={{ author.pk }}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
all_authors = models.Author.objects.all()
for author in all_authors:
print(author.books,type(author.books)) # 关系管理对象
print(author.books.all()) # 使用all,获取对应列表
# 增加作者
def add_author(request):
if request.method == ‘POST‘:
# 获取post请求提交数据
author_name = request.POST.get(‘author_name‘)
books = request.POST.getlist(‘books‘)
# 存入数据库
author_obj = models.Author.objects.create(name=author_name, )
author_obj.books.set(books)
# 跳转到展示页面
return redirect(‘/author_list/‘)
# 查询所有的书籍
all_books = models.Book.objects.all()
return render(request, ‘add_author.html‘, {‘all_books‘: all_books})
<form action="" method="post">
<p> 作者姓名: <input type="text" name="author_name"></p>
<p> 作品:
<select name="books" id="" multiple>
{% for book in all_books %}
<option value="{{ book.pk }}">{{ book.title }}</option>
{% endfor %}
</select>
</p>
<button>提交</button>
</form>
知识点:
# 删除作者
def del_author(request):
# 获取要删除对象的id
pk = request.GET.get(‘pk‘)
# 获取要删除的对象 删除
models.Author.objects.filter(pk=pk).delete()
# 跳转到展示页面
return redirect(‘/author_list/‘)
# 编辑作者
def edit_author(request):
# 查询编辑的作者对象
pk = request.GET.get(‘pk‘)
author_obj = models.Author.objects.get(pk=pk)
if request.method == ‘POST‘:
# 获取提交的数据
name = request.POST.get(‘author_name‘)
books = request.POST.getlist(‘books‘)
# 修改对象的数据
author_obj.name = name
author_obj.save()
# 多对多的关系
author_obj.books.set(books) # 每次重新设置
# 重定向
return redirect(‘/author_list/‘)
# 查询所有的书籍
all_books = models.Book.objects.all()
return render(request, ‘edit_author.html‘, {‘author_obj‘: author_obj, ‘all_books‘: all_books})
<form action="" method="post">
<p> 作者姓名: <input type="text" name="author_name" value="{{ author_obj.name }}"></p>
<p> 作品:
<select name="books" id="" multiple>
{% for book in all_books %}
{% if book in author_obj.books.all %}
<option value="{{ book.pk }}" selected>{{ book.title }}</option>
{% else %}
<option value="{{ book.pk }}">{{ book.title }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<button>提交</button>
</form>
注意:每次默认都是重新设置的
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField(‘Book‘) # 不在Author表中生产字段,生产第三张表
class AuthorBook(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
date = models.DateField()
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField(‘Book‘,through=‘AuthorBook‘)
class AuthorBook(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
date = models.DateField()
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField(‘Book‘,through=‘AuthorBook‘,through_fields=[‘author‘,‘book‘]
class AuthorBook(models.Model):
author = models.ForeignKey(Author,related_name=‘a‘ ,on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
tuijian = models.ForeignKey(Author,related_name=‘b‘,on_delete=models.CASCADE)
STATIC_URL = ‘/static/‘
STATICFILES_DIRS = [
os.path.join(BASE_DIR,‘static’),
]
标签:django框架 complete counter 属性 项目文件 对应关系 day 校验器 price
原文地址:https://www.cnblogs.com/yinhaiping/p/a572cc37eea509eab4a3986b8be7f20e.html