前言,Django安装

pip install django    # 官网安装最新版本
pip install django -i "https://pypi.doubanio.com/simple/" # 指定安装源
pip install django --upgrate # 更新Django
pip uninstall django # 卸载django
pip install django==1.11. -i http://pypi.douban.com/simple --trusted-host pypi.douban.com # 安装指定版本django

一、Django项目的url的实现

1)创建django框架,

第一步:创建 django框架
先创建文件夹,再在cmd里面输入下面内容,项目:小说
django-admin startproject url定义 第二步
文件夹内出现相应的子文件,创建app
cd blog
python manage.py startapp blog #创建novel应用,会出现novel文件夹,里面有很多.py文件
python3 manage.py runserver 第二步:访问
http://127.0.0.1:8000/ 首页

pycharm创建Django框架非常简单,一步到位

2)自定义url网页。HttpResponse 返回前端字符串内容

from blog import views     # 添加内容

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^show_time',views.show_time) # 添加内容
]

urls.py

from django.shortcuts import render,HttpResponse  # 补充的内容 

# Create your views here.

# 添加的函数
def show_time(req):
return HttpResponse("hello")

views.py

3行内容实现了自定义网页

3)以html文件返回给服务器。render 返回 html 内容

在上面的基础上运行

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello world</h1>
</body>
</html>

templates/index.html

def show_time(req):
return render(req,'index.html') # 修改这里即可

view.py

4)返回页面时间内容。技术点:html文件的{{ t }}  ===》views.show_time里面的变量t

  模板变量的使用

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello world {{ t }}</h1>
</body>
</html>

index.html

from django.shortcuts import render,HttpResponse
import time
# Create your views here. def show_time(req):
t=time.ctime()
return render(req, 'index.html',locals())

views.py

也可以换一种写法

HTML中  <h1>hello world {{ time }}</h1>

view.py中
def show_time(req):
t=time.ctime()
return render(req, 'index.html',{"time":t})

4.1)模板变量的使用

第一种:直接获取到变量
<h1>hello {{ name }}</h1>
第二种:获取到列表,使用索引取值
<h1>hello {{ name. }}</h1>
<h1>hello {{ name. }}</h1>
第三种:获取到字典,使用key取值
<h1>hello {{ name.name }}</h1>
第四种:获取到对象,使用对象属性取值
<h1>hello {{ name.name }}</h1>

html中对python变量的获取

4.2)模板过滤器

语法格式:     {{obj|filter:param}}

   #   add          :   给变量加上相应的值
#
# addslashes : 给变量中的引号前加上斜线
#
# capfirst : 首字母大写
#
# cut : 从字符串中移除指定的字符
#
# date : 格式化日期字符串
#
# default : 如果值是False,就替换成设置的默认值,否则就是用本来的值
#
# default_if_none: 如果值是None,就替换成设置的默认值,否则就使用本来的值

使用示例

#value1="aBcDe"
{{ value1|upper }}<br> #value2=
{{ value2|add: }}<br> #value3='he llo wo r ld'
{{ value3|cut:' ' }}<br> #import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br> #value5=[]
{{ value5|default:'空的' }}<br> #value6='<a href="#">跳转</a>' {{ value6 }} {% autoescape off %}
{{ value6 }}
{% endautoescape %} {{ value6|safe }}<br> {{ value6|striptags }} #value7=''
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br> #value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
value9='hello I am yuan'

4.3){% if %} 模板控制语句 if 判断

{% if num >=  and  %}

    {% if num >  %}
<p>num大于200</p>
{% else %}
<p>num大于100小于200</p>
{% endif %} {% elif num < %}
<p>num小于100</p> {% else %}
<p>num等于100</p> {% endif %} {% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
{% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的: {% if obj1 and obj2 or obj3 %}

if 判断

4.4){% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容

<ul>
{% for obj in list %}
<li>{{ obj.name }}</li>
{% endfor %}
</ul> #在标签里添加reversed来反序循环列表: {% for obj in list reversed %}
...
{% endfor %} #{% for %}标签可以嵌套: {% for country in countries %}
<h1>{{ country.name }}</h1>
<ul>
{% for city in country.city_list %}
<li>{{ city }}</li>
{% endfor %}
</ul>
{% endfor %} #系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量,
#这个变量含有一些属性可以提供给你一些关于循环的信息 ,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1: {% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0
,forloop.revcounter
,forloop.revcounter0
,forloop.first当第一次循环时值为True,在特别情况下很有用: {% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %} # 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了
# 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它
# Django会在for标签的块中覆盖你定义的forloop变量的值
# 在其他非循环的地方,你的forloop变量仍然可用 #{% empty %} {{li }}
{% for i in li %}
<li>{{ forloop.counter0 }}----{{ i }}</li>
{% empty %}
<li>this is empty!</li>
{% endfor %} # [, , , , ]
# ----
# ----
# ----
# ----
# ----

{% for %}

5)加上jquery-3.2.1.min.js 静态文件渲染

第一步:找到存放位置
在顶级目录下创建static文件夹,存放jquery-3.2..min.js文件 第二步:添加配置路径。settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS=(os.path.join(BASE_DIR,"static"),) 添加位置 第三步:html加入文件 <script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("h1").css("color","red")
</script>

特别注意:
<script src="/static/jquery-3.2.1.min.js"></script>
这里的static对应的是。STATIC_URL = '/static/' 这里的 STATICFILES_DIRS=(os.path.join(BASE_DIR,"static"),)
这里对应的是文件夹的static名字

6)引用jquery的推荐方法

<head>
<meta charset="UTF-8">
{% load staticfiles %} # 增加的方法
<title>Title</title>
</head>
<body>
<h1>hello world {{ time }}</h1>
{#<script src="/static/jquery-3.2.1.min.js"></script>#} 原来的方法
<script src="{% static 'jquery-3.2.1.min.js' %}"></script> 推荐使用的方法

二、简单的注册页面写入

1)注册页面使用get 请求时

第一步:添加路由
urls.py里面 url(r"register",views.register) 第二步:定义视图函数
views.py里面添加函数
def register(request):
print(request.GET)
print(request.GET.get('user'))
return render(request,'register.html') 第三步:templates里面添加 register.html 文件
写入 register.html 文件
register.html文件
<body>
<h1>学生注册</h1>
<hr>
<form action="http://127.0.0.1:8000/register" method="get">
<p>姓名<input type="text" name="user"></p>
<p>年龄<input type="text" name="age"></p>
<p>爱好<input type="checkbox" name="hobby" value="">篮球
<input type="checkbox" name="hpbby" value="">篮球
<input type="checkbox" name="hobby" value="">篮球
</p>
<p><input type="submit">提交</p>
</form>
</body>
</html>

register.html

都可以实现
<form action="http://127.0.0.1:8000/register/" method="post">
<form action="/register/" method="post">

2)注册页面使用 post 请求时

需要关闭settings.py里面的安全机制      'django.middleware.csrf.CsrfViewMiddleware',。否则请求会发生错误

<body>
<h1>学生注册</h1>
<hr>
<form action="http://127.0.0.1:8000/register" method="post">
<p>姓名<input type="text" name="user"></p>
<p>年龄<input type="text" name="age"></p>
<p>爱好<input type="checkbox" name="hobby" value="">篮球
<input type="checkbox" name="hpbby" value="">篮球
<input type="checkbox" name="hobby" value="">篮球
</p>
<p><input type="submit">提交</p>
</form>
</body>
</html>

register.html

def register(request):
print(request.POST)
print(request.POST.get('user'))
if request.method == "POST":
return HttpResponse("success!") # POST 请求之后返回的内容
return render(request,'register.html')

register函数 post请求

3)路由定义别名,实现动态的路由变化

第一步:路由定义别名
url(r"register", views.register,name="reg") 第二步:修改register.html
<head>
{% load staticfiles %}
........
<form action="{% url 'reg' %}" method="post">

4)url 路由分发(重点)

先在全局的urls文件中修改

from django.conf.urls import url,include   # 导入include
from django.contrib import admin from blog import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/',include('blog.urls')) # 指向blog路由
]

再在app里面添加urls文件

from django.conf.urls import url,include
from django.contrib import admin from blog import views urlpatterns = [
url(r'^show_time',views.show_time),
url(r"register", views.register,name="reg"),
]

访问访问效果


http://127.0.0.1:8000/register
http://127.0.0.1:8000/show_time
变成了
http://127.0.0.1:8000/blog/register
http://127.0.0.1:8000/blog/show_time

5)url路由跳转。redirect (重点)

urlpatterns = [
url(r'^show_time',views.show_time),
url(r"register", views.register,name="reg"), 注册界面
url(r'login',views.login), 被跳转的登录界面
] 第二步:定义函数
def register(request):
print(request.POST)
user = request.POST.get('user')
if user == "yuan":
return redirect("/blog/login/") # 跳转到指定的login路由
return render_to_response("register.html") def login(req):
return render(req,"login.html")

6)补充内容

 # return render(request,'register.html')  建议用这个
等效于
return render_to_response("register.html")

三、url的扩展,CBV模式(url==》class)

URL ---> 函数 ---> FBV
URL ---> 类 ---> CBV

1)匹配url规则模式,至上而下,匹配视图类

urlpatterns = [
url(r'^admin/',admin.site.urls),
url(r'^inx$',views.inx),
# 由于前面已经有inx,要匹配到inxd,一定要在后面加$
url(r'^inxd$',views.index), url(r'^cbv$',views.CBV.as_view()), # 匹配 views 里面的 class
]

urls.py

2)视图类的创建

from django.views import View
class CBV(View):
def get(self,request):
return HttpResponse('CBV.GET') def post(self,request):
return HttpResponse('CBV.POST')

views_class

3)自定义视图类的创建,类的扩展

from django.views import View
class CBV(View):
def dispatch(self,request,*args,**kargs):
result = super(CBV,self).dispatch(request,*args,**kargs)
return result def get(self,request):
# 根据请求头中的request method进行自动执行
# return HttpResponse('CBV.GET')
return render(request,'cbv.html') def post(self,request):
return HttpResponse('CBV.POST')

views_class

四、orm对models中创建表的操作

1) 选择数据库的引擎

第一种默认的数据库引擎。sqlite3

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

sqlite3

第二种,mysql数据库

# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# } DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books', #你的数据库名称
'USER': 'root', #你的数据库用户名
'PASSWORD': '', #你的数据库密码
'HOST': '', #你的数据库主机,留空默认为localhost
'PORT': '', #你的数据库端口
}
}

mysql数据库

需要替换驱动把mysqldb替换成pymysql

django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL
所以,我们只需要找到项目名文件下的__init__,在里面写入: import pymysql
pymysql.install_as_MySQLdb()

2)创建表

第一步:确定配置文件加入了app
INSTALLED_APPS = [
.................
'blog'
] 第二步:在models.py中写入class 表结构
# create table book(
# name varchar(),
# price float(,),
# )
class Book(models.Model):
name=models.CharField(max_length=)
price=models.FloatField()
pub_date=models.DateField() 第三步:生成数据库
python manage.py makemigrations
python manage.py migrate

创建过程

from django.db import models

# Create your models here.

  # create table book(

# name varchar(),
# price float(,),
# )
class Book(models.Model):
name = models.CharField(max_length=)
price = models.FloatField()
pub_date = models.DateField() class UserInfo(models.Model):
username = models.CharField(max_length=)
email = models.EmailField(max_length=)

models.py

name=models.CharField(max_length=20,verbose_name="姓名")  起别名
price=models.IntegerField("价格")   # 起别名

如果后面继续增加表结构:python manage.py makemigrations

python manage.py migrate

3)pycharm中查看创建的表

4)单表内容的增删改

第一步:查看表字段

class Book(models.Model):
name = models.CharField(max_length=)
price = models.FloatField()
pub_date = models.DateField()
author = models.CharField(max_length=,null=False)

表结构

前端网页显示

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> <style>
* {
margin: 0;
padding: 0;
}
.head{
line-height: 40px;
background-color: green;
color: white;
text-align: center;
}
</style>
</head>
<body>
<div class="outer">
<div class="head">标题</div>
<div class="content">
<a href="/addbook/">添加书籍</a>
<a href="/update/">修改书籍</a>
<a href="/delete/">删除书籍</a>
<a href="/select/">查询书籍</a>
</div>
<div class="queryResult">
{% for book in book_list %}
<div>
<p>{{ book.name }} {{ book.author }} {{ book.price }}</p>
</div>
{% endfor %} </div> </div>
</body>
</html>

index.html

配置相应的路由

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'index/', views.index),
url(r'^addbook/',views.addbook),
url(r'^update/', views.update),
url(r'^delete/', views.delete),
url(r'^select/', views.select),
]

urls.py

4.1)根据表字段执行添加内容

def addbook(request):
# 第一种
# b = Book(name="python基础",price=,author="egon",pub_date="2016-12-12")
# b.save() # 第二种
Book.objects.create(name="python进阶",price=,author="egon",pub_date="2017-02-12")
# Book.objects.create(**dic) 用户输入的字段完全一样的情况下
return HttpResponse("添加成功")

add

4.2)更新修改表内容

def update(request):
# 第一种,推荐使用,只对修改的字段赋值
Book.objects.filter(author="egon").update(price=) # 第二种,如果在sqlite可能会出错,实现原理,无论其他字段改没改,都重新赋值
# b=Book.objects.get(author="oldboy")
# b.price=
# b.save()
# print(b)#<QuerySet [<Book: Book object>]>
# print(type(b))
return HttpResponse("更新成功")

update

4.3)删除表内容

def delete(request):
Book.objects.filter(author="oldboy").delete()
return HttpResponse("删除成功"

delete

4.4)查看表内容

def select(request):
# 第一种查询全部
book_list = Book.objects.all()
# book_list = Book.objects.all()[:] # 列表特性,获取前3条记录
# book_list = Book.objects.all()[::]
# book_list = Book.objects.all()[::-] # book_list = Book.objects.filter(id=) # 只要用filter取出来的就是集合
# book = Book.objects.first() # 获取第一个元素
# book = Book.objects.last() # 获取最后一个元素
# book = Book.objects.get(id=) # 只能获取到1个,多条报错 # ret = Book.objects.filter(author="egon").values("name") # 查询到作者是egon的写的所有书名
# ret = Book.objects.filter(author="egon").values("name",'price') # 列表中的字典形式,获取到指定的字段内容
# ret = Book.objects.filter(author="egon").values_list("name", 'price') # 列表中的元组形式 book_list = Book.objects.exclude(author="egon").values("name",'price') # (排除)排除egon的内容
# values_list 该数据类型无法在前端调用的属性
# book_list = Book.objects.all().values("name").distinct() # 根据name字典去重
book_cont = Book.objects.all().values("name").distinct().count() # 确定有多少记录
return render(request,'index2.html',{"book_list":book_list})

select练习示例

查询归纳总结

# 查询相关API:

#  <>filter(**kwargs):      它包含了与所给筛选条件相匹配的对象
# <>all(): 查询所有结果
# <>get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 #-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()--------
# <>values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列
# <>exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
# <>order_by(*field): 对查询结果排序
# <>reverse(): 对查询结果反向排序
# <>distinct(): 从返回结果中剔除重复纪录
# <>values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
# <>count(): 返回数据库中匹配查询(QuerySet)的对象数量。
# <>first(): 返回第一条记录
# <>last(): 返回最后一条记录
# <>exists(): 如果QuerySet包含数据,就返回True,否则返回False。

select总结

models.gamedb_sun.objects.all().order_by('id').reverse()    反转需要和  order_by联合使用

start = models.gamedb_sun.objects.filter(data='2019-02-10').first()
end = models.gamedb_sun.objects.filter(data='2019-02-18').first()
start = start.id
end = end.id
print(start,end)
index_list = models.gamedb_sun.objects.filter(id__lt=end, id__gt=start)

4.5)万能的模糊查询之双下划线

def select(request):
#万能的 __
# book_list=Book.objects.filter(price__gt=).values("name","price") # 筛选出大于50的
book_list=Book.objects.filter(name__contains="P").values_list("name","price") # 筛选出name字段含有"P"
# __icontains 不区分大小写。前面含"i",则不区分大小写
return render(request,'index2.html',{"book_list":book_list})

select __ 模糊查询

双下划线(__)之单表条件查询总结

models.Tb1.objects.filter(id__lt=, id__gt=)   # 获取id大于1 且 小于10的值

models.Tb1.objects.filter(id__in=[, , ])   # 获取id等于11、、33的数据
models.Tb1.objects.exclude(id__in=[, , ]) # not in models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 models.Tb1.objects.filter(id__range=[, ]) # 范围bettwen and startswith,istartswith, endswith, iendswith,

__模型查询

4.6)查看调用的sql语句

对于每次创建一个对象,想显示对应的raw sql,需要在settings加上日志记录部分:

LOGGING = {
'version': ,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}

setting+sql_log

5)多表查询之一对多

class Book(models.Model):
name=models.CharField(max_length=)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey("Publish")
authors=models.ManyToManyField("Author") def __str__(self):
return self.name class Publish(models.Model):
name=models.CharField(max_length=)
city=models.CharField(max_length=) def __str__(self):
return self.name

models.py

第一步查看表结构

app01_book

app01_publish 

第一种:查询生成python的出版社的信息
# book_obj=Book.objects.get(name="python")
# print(book_obj.name)
# print(book_obj.pub_date)
#
# #一对多:book_obj.publish--------一定是一个对象
# print(book_obj.publish.name)
# print(book_obj.publish.city)
# print(type(book_obj.publish)) 第二种:查询记录(通过对象)
正向查询:A---> B正向:正向查按字段
book_obj = Book.objects.get(name="python")
pub_obj=book_obj.publish -----》书籍对象对应的出版社对象
pub_obj.name
反向查询:B---> A反向:反向查按表名小写_set
pub_obj = Publish.objects.filter(name = "人民出版社")
pub_obj.book_set.all().values("name","price") 第三种:查询人民出版社出过的所有书籍名字和价格
#方式一:
# pub_obj=Publish.objects.filter(name="人民出版社")[]
# ret=Book.objects.filter(publish=pub_obj).values("name","price")
# print(ret) #方式二
# pub_obj = Publish.objects.filter(name="人民出版社")[]
# print(pub_obj.book_set.all().values("name","price"))
#print(type(pub_obj.book_set.all())) #方式三
# ret=Book.objects.filter(publish__name="人民出版社").values("name","price")
# print(ret)

多表查询之一对多

6)多表操作之一对多的增删改查

class Book(models.Model):
name=models.CharField(max_length=)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey("Publish") # 创建的约束,约束条件下,默认生成的表字段加上 _id def __str__(self):
return self.name class Publish(models.Model):
name=models.CharField(max_length=)
city=models.CharField(max_length=)

models.py

app01_publish

app01_book

6.1)一对多中增加表内容

方式一
Book.objects.create(name="linux运维",price=,pub_date="2017-12-12",publish_id=) 方式二
publish_obj=Publish.objects.filter(name="人民出版社")[] # 找到人民出版社的id,赋值给book的publish
Book.objects.create(name="GO",price=,pub_date="2017-05-12",publish=publish_obj)

create_add

6.2)一对多中查询表内容

正常查询

#查询人民出版社出过的所有书籍名字和价格
方式一:
pub_obj=Publish.objects.filter(name="人民出版社")[]
ret=Book.objects.filter(publish=pub_obj).values("name","price")
print(ret) #方式二
pub_obj = Publish.objects.filter(name="人民出版社")[]
print(pub_obj.book_set.all().values("name","price"))
print(type(pub_obj.book_set.all()))

__  匹配多表查询。filter 和 __   ==》 跨表查询

ret=Book.objects.filter(publish__name="人民出版社").values("name","price")
print(ret) #python这本书出版社的名字
ret2=Publish.objects.filter(book__name="python").values("name")
print(ret2)
ret3=Book.objects.filter(name="python").values("publish__name")
print(ret3) ret4=Book.objects.filter(publish__city="北京").values("name")
print(ret4) ret5=Book.objects.filter(pub_date__lt="2017-07-01",pub_date__gt="2017-01-01").values("publish__name")
print(ret5)

7)多表操作之多对多

  7.1)ManyToManyField自动创建第三张虚拟的关系表

class Book(models.Model):
name=models.CharField(max_length=)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey("Publish")
authors=models.ManyToManyField("Author") # 会自动生成多对多的book_author的关系表 def __str__(self):
return self.name class Publish(models.Model):
name=models.CharField(max_length=)
city=models.CharField(max_length=) def __str__(self):
return self.name class Author(models.Model):
name=models.CharField(max_length=)
age=models.IntegerField(default=) def __str__(self):
return self.name

models.py

基本的查询

book_obj=Book.objects.get(id=)
print(book_obj.authors.all())
print(type(book_obj.authors.all())) author_obj=Author.objects.get(id=)
print(author_obj.book_set.all())

多对多基本查询

增加关系的表操作

通过对象的方式绑定关系
增加一条记录book_author的关系记录
book_obj=Book.objects.get(id=)
author_obj=Author.objects.get(id=)
book_obj.authors.add(author_objs)
# 第4本书的作者是2号作者 增加多条记录book_author的关系记录
book_obj=Book.objects.get(id=)
author_obj=Author.objects.all()
book_obj.authors.add(*author_objs)
第4本书的作者是所有的作者搞的 解除某书与作者之间的关系
book_obj=Book.objects.get(id=)
author_obj=Author.objects.all()
book_obj.authors.remove(*author_objs) 解除某书与作者的id关系
book_obj=Book.objects.get(id=)
author_obj=Author.objects.all()
book_obj.authors.remove() # 指解除书的id为3的,作者为2的关系

对比真实表比较查询。真实表的创建在后面

#alex出过的书籍名称及价格,真实表
ret=Book.objects.filter(book_author__author__name="alex").values("name","price")
print(ret) # ManyToManyField自动创建的虚拟表
ret2=Book.objects.filter(authors__name="alex").values("name","price","authors__name")
print(ret2)

真实与虚拟查询方法对比

补充内容

from django.db import models

class Classes(models.Model):
"""
班级表,男
"""
titile = models.CharField(max_length=)
m = models.ManyToManyField('Teachers',related_name='sssss') class Teachers(models.Model):
"""
老师表,女
"""
name = models.CharField (max_length=) class Student(models.Model):
"""
学生表
"""
username = models.CharField(max_length=)
age = models.IntegerField()
gender = models.BooleanField()
cs = models.ForeignKey(Classes,related_name='ssss') # cs,cs_id 3班 ######################## 单表 ########################
# 增加
# Teachers.objects.create(name='root')
# obj = Teachers(name='root')
# obj.save()
# 查
# Teachers.objects.all()
# Teachers.objects.filter(id=)
# Teachers.objects.filter(id=,name='root')
# result = Teachers.objects.filter(id__gt=)
# [obj(id,name),]
# result = Teachers.objects.filter(id__gt=).first()
# 删除
# Teachers.objects.filter(id=).delete()
# 改
# Teachers.objects.all().update(name='alex')
# Teachers.objects.filter(id=).update(name='alex') ######################## 一对多 ########################
"""
班级:
id name
3班
6班 学生
id username age gender cs_id
东北 男
东北1 男
东北1 男
"""
# 增加
# Student.objects.create(username='东北',age=,gender='男',cs_id=)
# Student.objects.create(username='东北',age=,gender='男',cs= Classes.objects.filter(id=).first() )
# 查看
"""
ret = Student.objects.all()
# []
# [ obj(..),]
# [ obj( 东北 男 ),obj( 东北1 男 ),obj(..),]
for item in ret:
print(item.id)
print(item.username)
print(item.age)
print(item.gender)
print(item.cs_id)
print(item.cs.id)
print(item.cs.name)
"""
# 删除
# Student.objects.filter(id=).delete()
# Student.objects.filter(cs_id=).delete() # cid = input('请输入班级ID')
# Student.objects.filter(cs_id=cid).delete() # cname = input('请输入班级名称')
# Student.objects.filter(cs_id=cid).delete()
# Student.objects.filter(cs__name=cname).delete() ######################## 多对多 ######################## # 多对多
"""
班级:
id title
3班
4班
5班
老师:
id title
Alex
老妖
瞎驴
Eric
老师班级关系表(类):
id 班级id 老师id # 增
obj = Classes.objects.filter(id=).first() # 3班
obj.m.add()
obj.m.add([,]) # obj = Classes.objects.filter(id=).first() # 3班
# obj.m.add()
# obj.m.add([,]) obj = Classes.objects.filter(id=).first() # 3班
# 删除
# obj.m.remove([,])
# 清空
obj.m.clear()
# 重置
obj.m.set([,,]) # 查第三张表
# 把3班的所有老师列举
obj = Classes.objects.filter(id=).frist()
obj.id
obj.titile
ret = obj.m.all() # 第三张表
# ret是一个 [ 老师1(id,name),obj(id,name) ] """
班级:
id name
3班
6班 class School:
name = models.CharField(max_length=) class Classes(models.Model):
"""
班级表,男
"""
titile = models.CharField(max_length=)
# m = models.ManyToManyField('Teachers') # 多对多
# sch = models.ForeignKey(School) 老师:
id title
Alex
老妖
瞎驴
Eric
class Teachers(models.Model):
"""
老师表,女
"""
name = models.CharField (max_length=) 学生
id username age gender cs_id
东北 男
东北1 男
东北1 男
class Student(models.Model):
"""
学生表
"""
username = models.CharField(max_length=)
age = models.IntegerField()
gender = models.BooleanField()
cs = models.ForeignKey(Classes) # 示例:
- 所有学生的姓名以及其所在班级名称,QuerySet
stu_list = Student.objects.all()
select * from tb;
[obj,obj,obj,obj] stu_list = Student.objects.all().values("id",'username')
select id,username from tb;
[{"id":,'username':'xx'},{id:'',username:''}] stu_list = Student.objects.all().values_list("id",'username')
[(,'root'), (,'alex')] stu_list = Student.objects.all().values('username',"cs__name")
for row in stu_list:
print(row['username'],row['cs__name']) stu_list = Student.objects.all().values('username',"cs__titile",“cs__fk__name”) - 找到3班的所有学生
Student.objects.filter(cs__name='3班') obj = Classes.objects.filter(name='3班').first()

7.2)聚合函数查询:aggregate(*args,**kwargs)

调用模块
from django.db.models import Avg,Min,Sum,Max,Count ret=Book.objects.all().aggregate(Avg("price"))
ret=Book.objects.all().aggregate(Sum("price"))
ret=Book.objects.filter(authors__name="alex").aggregate(Sum("price"))
ret=Book.objects.filter(authors__name="alex").aggregate(alex_money=Sum("price"))
ret=Book.objects.filter(authors__name="alex").aggregate(Count("name"))
print(ret) # 每一个作者出过的书的总价。涉及了分组
ret1=Book.objects.values("authors__name")
ret2=Book.objects.values("authors__name").annotate(Sum("price"))
print(ret2) # 每个出版社出版的价格最低的书
ret=Publish.objects.values("name").annotate(abc=Min("book__price"))
print(ret)

7.3)引入F查询和Q查询

引入F,Q 函数
from django.db.models import Q,F
# 对数据进行加减,引入F
Book.objects.all().update(price=F("price")+) # 找到价格是87或者是GO的,条件或,引入 Q
ret = Book.objects.filter(Q(price=)|Q(name="GO"))
# 找到不少GO的
ret = Book.objects.filter(^Q(name="GO"))
# Q查询也关键字查询组合使用,但Q查询一定要写在前面
ret=Book.objects.filter(Q(name="GO"),price=)
print(ret)

7.4)ORM的querySet集合对象特性。可节约内存的方式

ret = Book.objects.filter(price=)
# 如果不使用ret,则不执行sql语句
for i in ret:
print(i.price) if ret.exists(): # 仅仅是判断有没有值,不会把查询结果存在内存中
print("ok") 节省内存,变化成迭代器
ret=ret.iterator()
print(ret) for i in ret:
print(i.name)

7.5)models.py 创建第三张真实表的关系表

class Book(models.Model):
name=models.CharField(max_length=)
price=models.IntegerField()
pub_date=models.DateField()
publish=models.ForeignKey("Publish") def __str__(self):
return self.name class Publish(models.Model):
name=models.CharField(max_length=)
city=models.CharField(max_length=) def __str__(self):
return self.name class Book_Author(models.Model):
book=models.ForeignKey("Book")
author=models.ForeignKey("Author") class Author(models.Model):
name=models.CharField(max_length=)
age=models.IntegerField(default=) def __str__(self):
return self.name

models.py

表关系应用。虚拟表在上面

#创建第三张表
Book_Author.objects.create(book_id=,author_id=)
# 通过id为2的书的作者
obj=Book.objects.get(id=)
print(obj.book_author_set.all()[].author) #alex出过的书籍名称及价格
ret=Book.objects.filter(book_author__author__name="alex").values("name","price")
print(ret)

真实与虚拟查询方法对比

8)模型中常用的字段类型参数

<> CharField
#字符串字段, 用于较短的字符串.
#CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数. <> IntegerField
#用于保存一个整数. <> FloatField
# 一个浮点数. 必须 提供两个参数:
#
# 参数 描述
# max_digits 总位数(不包括小数点和符号)
# decimal_places 小数位数
# 举例来说, 要保存最大值为 (小数点后保存2位),你要这样定义字段:
#
# models.FloatField(..., max_digits=, decimal_places=)
# 要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
#
# models.FloatField(..., max_digits=, decimal_places=)
# admin 用一个文本框(<input type="text">)表示该字段保存的数据. <> AutoField
# 一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
# 自定义一个主键:my_id=models.AutoField(primary_key=True)
# 如果你不指定主键的话,系统会自动添加一个主键字段到你的 model. <> BooleanField
# A true/false field. admin 用 checkbox 来表示此类字段. <> TextField
# 一个容量很大的文本字段.
# admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框). <> EmailField
# 一个带有检查Email合法性的 CharField,不接受 maxlength 参数. <> DateField
# 一个日期字段. 共有下列额外的可选参数:
# Argument 描述
# auto_now 当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.
# auto_now_add 当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
#(仅仅在admin中有意义...) <> DateTimeField
# 一个日期时间字段. 类似 DateField 支持同样的附加选项. <> ImageField
# 类似 FileField, 不过要校验上传对象是否是一个合法图片.#它有两个可选参数:height_field和width_field,
# 如果提供这两个参数,则图片将按提供的高度和宽度规格保存.
<> FileField
# 一个文件上传字段.
#要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting,
#该格式将被上载文件的 date/time
#替换(so that uploaded files don't fill up the given directory).
# admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) . #注意:在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
#()在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件.
# (出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 作为该目录的公共 URL. 要确保该目录对
# WEB服务器用户帐号是可写的.
#() 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
# 使用 MEDIA_ROOT 的哪个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT).
# 出于习惯你一定很想使用 Django 提供的 get_<#fieldname>_url 函数.举例来说,如果你的 ImageField
# 叫作 mug_shot, 你就可以在模板中以 {{ object.#get_mug_shot_url }} 这样的方式得到图像的绝对路径. <> URLField
# 用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且
# 没有返回404响应).
# admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框) <> NullBooleanField
# 类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项
# admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据. <> SlugField
# "Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们通常用于URLs
# 若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: . #在
# 以前的 Django 版本,没有任何办法改变50 这个长度.
# 这暗示了 db_index=True.
# 它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-#populate
# the slug, via JavaScript,in the object's admin form: models.SlugField
# (prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields. <> XMLField
#一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径. <> FilePathField
# 可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
# 参数 描述
# path 必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目.
# Example: "/home/images".
# match 可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名.
# 注意这个正则表达式只会应用到 base filename 而不是
# 路径全名. Example: "foo.*\.txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
# recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
# 这三个参数可以同时使用.
# match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
# FilePathField(path="/home/images", match="foo.*", recursive=True)
# ...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif <> IPAddressField
# 一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
<># CommaSeparatedIntegerField
# 用于存放逗号分隔的整数值. 类似 CharField, 必须要有maxlength参数.

9)field 重要参数

<> null : 数据库中字段是否可以为空

    <> blank: django的 Admin 中添加数据时是否可允许空值

    <> default:设定缺省值

    <> editable:如果为假,admin模式下将不能改写。缺省为真

    <> primary_key:设置主键,如果没有设置django创建表时会自动加上:
id = meta.AutoField('ID', primary_key=True)
primary_key=True implies blank=False, null=False and unique=True. Only one
primary key is allowed on an object. <> unique:数据唯一 <> verbose_name  Admin中字段的显示名称 <> validator_list:有效性检查。非有效产生 django.core.validators.ValidationError 错误 <> db_column,db_index 如果为真将为此字段创建索引 <>choices:一个用来选择值的2维元组。第一个值是实际存储的值,第二个用来方便进行选择。
如SEX_CHOICES= (( ‘F’,'Female’),(‘M’,'Male’),)
gender = models.CharField(max_length=,choices = SEX_CHOICES)

原文出处:https://www.cnblogs.com/yuanchenqi/articles/6083427.html

Django之url定义和ORM框架的使用的更多相关文章

  1. Django(三) 模型:ORM框架、定义模型类并创建一个对应的数据库、配置Mysql数据库

    一.模型概述 https://docs.djangoproject.com/zh-hans/3.0/intro/tutorial02/ https://www.runoob.com/django/dj ...

  2. Django框架之数据库ORM框架

    首先,我来介绍一下什么是ORM框架: O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思.在ORM框架中,它帮 ...

  3. django之路由分组,路由分发,FBV,CBV,ORM框架

    今日的内容: a. 路由系统 1. 创建app 2. 路由的分组 3. 路由的分发 - 正则表达式匹配 b. django的orm(模型model) 1. 创建模型的步骤 2. orm基本的增删改查 ...

  4. Django学习(三)---Models(ORM框架)

    1) Django 中Models是与数据库相关的,与数据库相关的代码一般写在 models.py中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在sett ...

  5. Django中的ORM框架使用小技巧

      Django中的ORM框架使用小技巧 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. Django对各个数据提供了很好的支持,包括PostgreSQL,MySQL,SQLite ...

  6. Django应用app创建及ORM

    一.重要知识点回顾: 1. form表单提交数据的注意事项: 1. 是form不是from,必须要有method和action (action用来指定你的数据提交到后台哪个地方,method用来指定你 ...

  7. Django之URL路由系统

    一 URL配置 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表.你就是以这 ...

  8. Django之URL(路由系统)用法

    路由系统 路由系统概念 简而言之,路由系统就是路径和视图函数的一个对应关系.django的路由系统作用就是使views里面处理数据的函数与请求的url建立映射关系.使请求到来之后,根据urls.py里 ...

  9. Django之URL控制器(路由层)

    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), 一.视图层路由配置系统 URL配置(URLconf)就像Django ...

随机推荐

  1. 织梦 百度sitemap制作教程

    一.新建一个sitemap.htm模板 登录dedecms后台,选择[模板]-[模板管理]-[默认模板管理] 点击最下面的[新建模板]新建一个模板,并复制下面这段代码进去(将代码中的域名改为自己的): ...

  2. 数论----gcd和lcm

    gcd即最大公约数,lcm即最小公倍数. 首先给出a×b=gcd×lcm 证明:令gcd(a,b)=k,a=xk,b=yk,则a×b=x*y*k*k,而lcm=x*y*k,所以a*b=gcd*lcm. ...

  3. Centos 7 MariaDB Galera cluster 部署

    一.安装环境准备 1.系统: CentOS Linux release 7.4.1708 (Core) 2.hosts 10.6.32.51 openstack1 10.6.32.52 opensta ...

  4. f5负载均衡算法

    负载均衡使用一种算法或公式来确定由哪一个后台服务器接收流量 负载均衡是基于连接的 1.静态负载均衡算法:以固定方式分发连接 轮询算法(Round Robin):将请求依次顺序循环地分发给服务器,从1到 ...

  5. Bootstrap(5)栅格系统

    一.移动设备优先 在 HTML5 的项目中,我们做了移动端的项目.它有一份非常重要的 meta,用于设置屏幕和设备等宽以及是否运行用户缩放,及缩放比例的问题. //分别为:屏幕宽度和设备一致.初始缩放 ...

  6. xss测试用例

    alert(1)// 'alert(1)// '>alert(1)// >alert(1)// "alert(1)// ">alert(1)// alert(1) ...

  7. [z]oracle优化http://jadethao.iteye.com/blog/1613943

    [sql] view plaincopy SQL> create table t as select 1 id,object_name from dba_objects; Table creat ...

  8. asp.net core webapi 似乎未安装在 IIS 中承载 .NET Core 项目所需的 AspNetCoreModule。请尝试修复 Visual Studio 以纠正该问题。

    安装 DotNetCore.1.1.0-WindowsHosting 后,提示如题错误. 解决办法: ASP.NET Core 应用程序运行,可以选择 IIS Express 也可以选择 自己运行 , ...

  9. javascript 生存周期

    生存周期: 局部 JavaScript 变量 在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它.(该变量的作用域是局部的). 您可以在不同的函数中使用名 ...

  10. angular2.0学习笔记7.echarts 地图(type:'map')slice undifined 出错问题

    在 项目\node_modules\echarts\lib\chart\map.js文件头部 ... ... require("../coord/geo/geoCreator"); ...