Django目录:https://www.jianshu.com/p/dc36f62b3dc5
Yuan先生-Django 模型层(1)
Django与SQLAlchemy的ORM操作本质上是一样的,但是语法略有不同,如果是用Django进行开发最好使用原生的ORM或者直接使用原生SQL。
创建表
创建模型
在app06中的models.py文件内,新建一个模板。
one_exa.app06.models.py
-----------------------
from django.db import models
# Create your models here.
class Book(models.Model):
id = models.AutoField(primary_key=True) # id
name = models.CharField(max_length=32) # 书名
pub_date = models.DateField() # 出版日期
author = models.CharField(max_length=32) # 出版社
price = models.DecimalField(max_digits=8,decimal_places=2) # 价格
字段介绍
每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:
<1> CharField
字符串字段, 用于较短的字符串.
CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数.
<2> IntegerField
#用于保存一个整数.
<3> FloatField
一个浮点数. 必须 提供两个参数:
参数 描述
max_digits 总位数(不包括小数点和符号)
decimal_places 小数位数
举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段:
models.FloatField(..., max_digits=5, decimal_places=2)
要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
models.FloatField(..., max_digits=19, decimal_places=10)
admin 用一个文本框()表示该字段保存的数据.
<4> AutoField
一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
自定义一个主键:my_id=models.AutoField(primary_key=True)
如果你不指定主键的话,系统会自动添加一个主键字段到你的 model.
<5> BooleanField
A true/false field. admin 用 checkbox 来表示此类字段.
<6> TextField
一个容量很大的文本字段.
admin 用一个
参数介绍
(1)null
如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.
(1)blank
如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
(2)default
字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
(3)primary_key
如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。
(4)unique
如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
(5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,
而且这个选择框的选项就是choices 中的选项。
setting配置
如果先把模型变成数据库中的表,还需要在setting.py文件中配置数据库相关信息与注册app:
one_exa.one_exa.setting.py
--------------------------
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app05',
'app06'
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #声明数据库基类
'NAME':'django_orm', # 要连接的数据库,连接前需要创建好
'USER':'root', # 连接数据库的用户名
'PASSWORD':' ', # 连接数据库的密码
'HOST':'127.0.0.1', # 连接主机,默认本级
'PORT':3306 # 端口 默认3306
}
}
同时我们要在项目下的__ init__.py文件中声明我们使用的是pymysql。
one_exa.one_exa.__init__.py
---------------------------
import pymysql
pymysql.install_as_MySQLdb()
最后通过两条数据库迁移命令即可在指定的数据库中创建表 :
python manage.py makemigrations
python manage.py migrate
- 注意点1:
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
如报以上错误,是因为MySQLclient不支持当前版本Python,需要修改如下:
在Python放包的那个目录里面找:
这是我的路径
D:\Anaconda\Lib\site-packages\django\db\backends\mysql
把路径中的base.py中的
if version < (1, 3, 13):
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
注释掉。
- 注意点2:
如果想打印orm转换过程中的sql,需要在settings中进行如下配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
单表操作
修改路由表,分发路由,视图函数,html页面
one_exa.one_exa.urls.py
-----------------------
from django.urls import re_path,include
urlpatterns = [
re_path(r'^Journal/', include("app01.urls")),
re_path(r'^echarts/', include("app02.urls",namespace='visible')),
re_path(r'^fxjx/', include("app03.urls",namespace='booktest')),
re_path(r'^app04/', include("app04.urls")),
re_path(r'^app05/', include("app05.urls")),
re_path(r'^book/', include("app06.urls"))
]
one_exa.app06.urls.py
---------------------
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'ZSGC/', views.index),
re_path(r'addbook/', views.addbook),
re_path(r'update/', views.update),
re_path(r'delete/', views.delete),
re_path(r'select/', views.select)
]
one_exa.app06.views.py
----------------------
from django.shortcuts import HttpResponse,render
# Create your views here.
from .models import Book
def index(request):
return render(request,"ZSGC.html")
def addbook(request):
pass
def update(request):
pass
def delete(req):
pass
def select(req):
pass
one_exa.templates.ZSGC.html
---------------------------
Title
增
增加数据有两种方式,使用create()函数和先实例化类再使用save()添加到数据库内。
第一种方式:
Book.objects.create(name="老男孩linux",price=78,author="oldboy",pub_date="2016-12-12")
修改一下视图函数:
one_exa.app06.views.py
----------------------
from django.shortcuts import HttpResponse,render
# Create your views here.
from .models import Book
def index(request):
return render(request,"ZSGC.html")
def addbook(request):
Book.objects.create(name="老男孩linux",price=78,author="oldboy",pub_date="2016-12-12")
return HttpResponse("添加成功")
def update(request):
pass
def delete(req):
pass
def select(req):
pass
第二种方式:
b=Book(name="python基础",price=99,author="yuan",pub_date="2017-12-12")
b.save()
修改一下视图函数:
one_exa.app06.views.py
----------------------
from django.shortcuts import HttpResponse,render
# Create your views here.
from .models import Book
def index(request):
return render(request,"ZSGC.html")
def addbook(request):
b=Book(name="python基础",price=99,author="yuan",pub_date="2017-12-12")
b.save()
return HttpResponse("添加成功")
def update(request):
pass
def delete(req):
pass
def select(req):
pass
我们在数据库添加十条数据,来完成接下来的操作。
查
- 查询API
1.all()
查询所有结果
def select(req):
book_list=Book.objects.all()
return render(req, "ZSGC.html", {"book_list": book_list})
2.filter()
它包含了与所给筛选条件相匹配的对象
def select(req):
book_list = Book.objects.filter(author="alex")
return render(req, "ZSGC.html", {"book_list": book_list})
3.get()
返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
def select(req):
book_list = Book.objects.get(id = 6) #只能取出一条记录时才不报错
return render(req, "ZSGC.html", {"book_list": book_list})
因为取出的是一条记录,不是可迭代对象,所以页面也要修改一下:
{# {% for book in book_list %}#}
{# #}
{{ book_list.name }} - {{ book_list.author }} - {{ book_list.price }}
{# #}
{# {% endfor %}#}
4.exclude()
它包含了与所给筛选条件不匹配的对象(not)
def select(req):
book_list = Book.objects.exclude(author="alex")
return render(req, "ZSGC.html", {"book_list": book_list})
5.order_by()
对查询结果排序
def select(req):
book_list = Book.objects.order_by('price') #降序是'-price'
return render(req, "ZSGC.html", {"book_list": book_list})
6.reverse()
对查询结果反向排序
def select(req):
book_list = Book.objects.order_by('price').reverse()
return render(req, "ZSGC.html", {"book_list": book_list})
7.count()
返回数据库中匹配查询(QuerySet)的对象数量。
def select(req):
book_list = Book.objects.all().count()
print(book_list)
--------
输出结果:10
8.first()
返回第一条记录
def select(req):
book_list = Book.objects.all().first()
return render(req, "ZSGC.html", {"book_list": book_list})
#记得把页面修改成单p标签
9.last()
返回最后一条记录
def select(req):
book_list = Book.objects.all().last()
return render(req, "ZSGC.html", {"book_list": book_list})
10.exists()
如果QuerySet包含数据,就返回True,否则返回False
用来检测是否有符合条件的记录。
def select(req):
book_list = Book.objects.filter(author="han").exists()
print(book_list)
----------
输出结果:False
11.values()
返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列。
def select(req):
book_list = Book.objects.filter(author="wu").values("name")
print(book_list)
print(type(book_list))
return render(req, "ZSGC.html", {"book_list": book_list})
----------
输出结果:
12.values_list()
它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列。
def select(req):
book_list = Book.objects.filter(author="wu").values_list("name","price")
print(book_list)
print(type(book_list))
return render(req, "ZSGC.html", {"book_list": book_list})
----------
输出结果:
13.distinct()
从返回结果中剔除重复纪录。
数据库添加两条数据做对比
def select(req):
book_list = Book.objects.all().values("name","author","price") #对照组
return render(req, "ZSGC.html", {"book_list": book_list})
加上distinct()
def select(req):
book_list = Book.objects.all().values("name","author","price").distinct()
return render(req, "ZSGC.html", {"book_list": book_list})
14.aggregate()
对查询结果进行聚合操作
def select(req):
from django.db.models import Avg
book_list = Book.objects.all().aggregate(Avg("price"))
print(book_list)
----------
输出结果:{'price__avg': Decimal('124.750000')}
15.annotate()
对查询结果分组操作
def select(req):
from django.db.models import Count
book_list = Book.objects.values("author").annotate(auNum=Count("author"))
for i in book_list:
print(i)
----------
输出结果:
{'author': 'oldboy', 'auNum': 2}
{'author': 'yuan', 'auNum': 3}
{'author': 'wu', 'auNum': 3}
{'author': 'alex', 'auNum': 4}
- 模糊查询
1.XX__in
是否包含在范围内。
#查询价格为 99,109,189的书籍信息
def select(req):
book_list = Book.objects.all().filter(price__in=[99,109,189])
return render(req, "ZSGC.html", {"book_list": book_list})
2.gt,gte,lt,lte
大于,大于等于,小于,小于等于
#查询价格大于100的书籍信息
def select(req):
book_list = Book.objects.all().filter(price__gt=100)
return render(req, "ZSGC.html", {"book_list": book_list})
#查询价格小于100的书籍信息
def select(req):
book_list = Book.objects.all().filter(price__lt=100)
return render(req, "ZSGC.html", {"book_list": book_list})
4.contains
是否包含。
#查询书籍名带Python的书籍信息
def select(req):
book_list = Book.objects.all().filter(name__contains="python")
return render(req, "ZSGC.html", {"book_list": book_list})
5.isnull
是否为null。
#查询价格非空的书籍信息
def select(req):
book_list = Book.objects.all().filter(price__isnull=False)
return render(req, "ZSGC.html", {"book_list": book_list})
6.startswith,endswith
以指定值开头或结尾。
#查询以‘d’开头的书籍信息
def select(req):
book_list = Book.objects.all().filter(name__startswith="d")
return render(req, "ZSGC.html", {"book_list": book_list})
#查询以‘基础’结尾的书籍信息
def select(req):
book_list = Book.objects.all().filter(name__endswith="基础")
return render(req, "ZSGC.html", {"book_list": book_list})
7.year、month、day、week_day、hour、minute、second
对日期时间类型的属性进行运算。
#查询18年出版的图书
def select(req):
book_list = Book.objects.all().filter(pub_date__year="2018")
return render(req, "ZSGC.html", {"book_list": book_list})
删
删除操作在查询操作的基础上,使用delete()进行删除。
def delete(req):
Book.objects.filter(author="oldboy").delete()
return HttpResponse("删除成功!")
改
修改操作在查询操作的基础上,使用update()进行删除。
def update(request):
Book.objects.filter(author="yuan").update(price=999)
return HttpResponse("修改成功!")