网站开发哪种语言最好,网站建设疑问,动易 网站首页,网页加速器免费永久Django模型层(附带test环境) 目录 Django模型层(附带test环境)连接数据库Django ORM在models.py中建表允许为空指定默认值数据库迁移命令 开启测试环境建表语句补充(更改默认表名)数据的增加时间数据的时区 多表数据的增加一对多多对多 数据的删除修改数据查询数据查询所有数据…Django模型层(附带test环境) 目录 Django模型层(附带test环境)连接数据库Django ORM在models.py中建表允许为空指定默认值数据库迁移命令 开启测试环境建表语句补充(更改默认表名)数据的增加时间数据的时区 多表数据的增加一对多多对多 数据的删除修改数据查询数据查询所有数据去重查询排序查询统计剔除指定数据多表查询示例一对多图书与出版社多对多图书和作者方式【1】**推荐**方式【2】**不推荐** 校验数据是否存在字段的筛选查询连表查询正向查询反向查询 聚合函数(aggregate)分组查询F与Q查询F查询Q查询 Django开启事务choices参数 连接数据库
这是Django默认的数据库
DATABASES {default: {ENGINE: django.db.backends.sqlite3,NAME: BASE_DIR / db.sqlite3,}
}修改为我们需要的配置
DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: mydj,USER: root,PASSWORD: 7997,HOST: 127.0.0.1,PORT: 3306,CHARSET: utf8,}
}django 默认使用mysqldb模块链接mysql 但是该模块的兼容性不好需要手动修改为pymysql链接 在项目下的init或者任意的应用名下的init文件中书写一下代码 init.py
import pymysqlpymysql.install_as_MySQLdb()Django ORM
在models.py中建表
id字段Django会自动帮忙创建
from django.db import models# Create your models here.
class User(models.Model):username models.CharField(max_length32)password models.CharField(max_length32)允许为空
class MyModel(models.Model):name models.CharField(max_length50, nullTrue) # 允许name字段为空指定默认值
class MyModel(models.Model):age models.IntegerField(default18) # 默认年龄为18岁数据库迁移命令 创建操作记录 python manage.py makemigrations操作完后Django会自动在migrations目录下生成sql语句文件 同步到数据库 python manage.py migrate等待表创建完毕 这样就是成功执行建表语句了
删除字段只要在models中删除对应的字段行然后重新makemigrations即可生成新的sql语句
开启测试环境
首先在app下找到tests.py文件并进入 MyDJ.settings要换成自己的项目名我的是MyDJ
import osfrom django.test import TestCaseif __name__ __main__:# 导入一句话 来自于 manage.py 中的第一句话os.environ.setdefault(DJANGO_SETTINGS_MODULE, MyDJ.settings)import djangoimport datetime# 启动Djangodjango.setup()from app01 import models# 开始业务代码user models.user.objects.create(username张三,password222)成功~
建表语句补充(更改默认表名)
class Book(models.Model):# 书名title models.CharField(max_length32)# 定价price models.IntegerField()# 出版日期publish_date models.DateTimeField(auto_nowTrue)# 绑定出版社外键publish models.ForeignKey(Publish, on_deletemodels.CASCADE, to_fieldid, default1)# 绑定图书表和作者表用ManyToManyField自动创建第三张表author models.ManyToManyField(Author)class Meta():# 不添加的话默认表名app01_bookdb_table book数据的增加
data models.user.objects.create(username李四,password929)data models.user(username陈五,password909)
data.save()时间数据的时区
创建时间字段(如DateTimeField())
中国时区需要将settings中部分设置修改为
LANGUAGE_CODE zh-hansTIME_ZONE Asia/Shanghai多表数据的增加
一对多
此时有一张作者表和作者详情表
作者详情表绑定这作者表的id
class Author(models.Model):# 作者名name models.CharField(max_length32, uniqueTrue)# 年龄age models.IntegerField()class Meta():db_table authorclass AuthorDetail(models.Model):# 作者电话phone models.CharField(max_length11)# 作者地址addr models.CharField(max_length132)# 作者名 绑定外键author_name models.ForeignKey(Author, on_deletemodels.CASCADE, to_fieldid, default1, nullTrue)class Meta():db_table authordetail对外键关系表进行增加操作
import osfrom django.test import TestCase
import datetimeif __name__ __main__:os.environ.setdefault(DJANGO_SETTINGS_MODULE, MyDJ.settings)import djangoimport datetimedjango.setup()from app01 import models# author_name内必须是一个Author实例对象不能直接使用参数内容models.Author.objects.create(name张三, age11)detail_id models.Author.objects.get(id1)models.AuthorDetail.objects.create(phone123, addr北京, author_namedetail_id)多对多
假设有一张图书表和作者表两者由第三张表绑定外键关系
class Book(models.Model):# 书名title models.CharField(max_length32)# 定价price models.IntegerField()# 出版日期publish_date models.DateTimeField(auto_nowTrue)# 绑定图书表和作者表用ManyToManyField自动创建第三张表author models.ManyToManyField(Author)class Meta():# 不添加的话默认表名app01_bookdb_table bookclass Author(models.Model):# 作者名name models.CharField(max_length32, uniqueTrue)# 年龄age models.IntegerField()class Meta():db_table authorimport osfrom django.test import TestCase
import datetimeif __name__ __main__:os.environ.setdefault(DJANGO_SETTINGS_MODULE, MyDJ.settings)import djangoimport datetimedjango.setup()from app01 import models# 为作者和图书的多对多的第三张表添加信息author_obj models.Author.objects.get(id1)book_obj models.Book.objects.get(id1)book_obj.author.add(author_obj)# 删除外键关系author_obj models.Author.objects.get(id1)book_obj models.Book.objects.get(id1)book_obj.author.remove(author_obj)# 修改外键关系author_obj models.Author.objects.get(id2)book_obj models.Book.objects.get(id1)book_obj.author.set([author_obj])# 清空外键关系book_obj models.Book.objects.get(id1)book_obj.author.clear()author_obj获取作者表实例
book_obj获取图书表实例 book_obj.author.add(author_obj)add内的参数是author表的实例
数据的删除
data models.user.objects.filter(username张三).delete()data models.user.objects.get(id9)
data.delete()修改数据
data models.user.objects.get(id10)
data.password111
data.save()data models.user.objects.filter(id10).update(username张三)查询数据
data models.user.objects.filter(id3)
print(data.values())# get不能查询不存在的数据否则会报错
data models.user.objects.get(id1)查询所有数据
# 查询所有数据
data models.user.objects.values()# id1的所有字段
data models.user.objects.filter(id1).values()# 元组查询结果只有值没有键
data models.user.objects.values_list()
data models.user.objects.filter(id1).values_list()去重查询
# 相同的username字段不会被多次查询
data models.user.objects.values(username).distinct()
print(data)data models.user.objects.values(username,password).distinct()排序查询
# 从小到大
data models.user.objects.order_by(id).values(id)# 从大到小
data models.user.objects.order_by(-id).values(id)统计
# 统计库中所有数据
data models.user.objects.values().count()# 库中名为admin的数量
data models.user.objects.filter(usernameadmin).count()剔除指定数据
# 排除id1的数据
data models.user.objects.values().exclude(id1)多表查询
假设有user、user2两个模型
# 一对多
data models.user.objects.select_related(user2).all()# 多对多
users User.objects.prefetch_related(user2).all()示例
创建book(书籍),Publish(出版社),Author(作者),AuthorDetail(作者详情)四个表
import datetimefrom django.db import modelsclass Book(models.Model):# 书名title models.CharField(max_length32)# 定价price models.IntegerField()# 出版日期publish_date models.DateTimeField(auto_nowdatetime.datetime.now())class Publish(models.Model):# 出版社名name models.CharField(max_length32)# 出版社地址addr models.CharField(max_length132)# 出版社邮箱email models.CharField(max_length32)class Author(models.Model):# 作者名name models.CharField(max_length32)# 年龄age models.IntegerField()class AuthorDetail(models.Model):# 作者电话phone models.CharField(max_length11)# 作者地址addr models.CharField(max_length132)# 创建迁移文件
python manage.py makemigrations
python manage.py migrate一对多图书与出版社 一个出版社可以有多本图书但是一本书只能有一个出版社 class Book(models.Model):# 书名title models.CharField(max_length32)# 定价price models.IntegerField()# 出版日期publish_date models.DateTimeField(auto_nowdatetime.datetime.now())# 绑定出版社外键publish models.ForeignKey(Publish,on_deletemodels.CASCADE,to_fieldid,default1, nullTrue)models.ForeignKey(Publish与Publish表关联
on_deletemodels.CASCADE指定外键关系(当图书信息被删除时出版社信息也会被删除)
to_fieldid,default1绑定author表的id主键并默认为1
多对多图书和作者 一本书可以有多个作者一个作者也可以创作多本书 方式【1】推荐
在Book类中使用ManyToManyField自动创建第三张表
# 绑定图书表和作者表用ManyToManyField自动创建第三张表
author models.ManyToManyField(Author)方式【2】不推荐
手动创建第三张表
class Book_Author(models.Model):book models.ForeignKey(Book,on_deletemodels.CASCADE())author models.ForeignKey(Author,on_deletemodels.CASCADE())手动制定ManyToManyField参数
through绑定的第三张表
through_fields绑定所需的字段 author models.ManyToManyField(toAuthor,throughBook_Author,through_fields(book,author))校验数据是否存在
data models.user.objects.filter(id1).exists()
print(data) # True/False字段的筛选查询
条件运算
大于gt
data models.user.objects.filter(id__gt5)小于lt
data models.user.objects.filter(id__lt5)大于等于gte
data models.user.objects.filter(id__gte5)小于等于lte
data models.user.objects.filter(id__lte5)或in
data models.user.objects.filter(id__in[1, 2, 3])两个条件之间range
# 顾头顾尾 因此返回id1,2,3的数据
data models.user.objects.filter(id__range[1,3]).values()模糊查询contains默认区分大小写
data models.user.objects.filter(username__contains三).values()模糊查询取消大小写限制icontains
data models.user.objects.filter(username__icontains三).values()以指定字符开头/结尾startswith/endswitch
data models.user.objects.filter(username__startswith张).values()过滤指定时间区间time
# 过滤时间小于当前时间的数据
current_time datetime.datetime.now()
data models.user.objects.filter(up_time__ltcurrent_time).values()连表查询
对于已经绑定了外键的字段可以使用连表查询一次查询不同表中的数据 示例中有一个author表和authordetail表authordetail的author_name_id字段绑定了author的id主键
正向查询
于是便可以通过获取author表中的示例然后.values(authordetail__phone)获取authordetail表中的phone字段如下
author_obj models.Author.objects.filter(name张三).values(authordetail__phone)
print(author_obj)反向查询
当要使用没有绑定外键的字段来查询有外键字段的内容时
author_obj models.AuthorDetail.objects.filter(author_name__name张三).values(author_name__name,phone)print(author_obj)聚合函数(aggregate)
聚合函数需要在分组的情况下使用并且需要导入Django中内置的聚合模块
from django.db.models import Avg, Sum, Max, Min, Countavg_price models.Book.objects.aggregate(Avg(price))
print(avg_price) # 获取书的平均价格
sum_price models.Book.objects.aggregate(Sum(price))
print(sum_price) # 获取书的总价
max_price models.Book.objects.aggregate(Max(price))
print(max_price) # 获取最贵的书
min_price models.Book.objects.aggregate(Min(price))
print(min_price) # 获取最便宜的书
count_price models.Book.objects.aggregate(Count(price))
print(count_price) # 获取书的数量分组查询
查询每本书有几个作者作者绑定外键
书 作者 绑定的外键表 book_obj models.Book.objects.annotate(aCount(author)).values(a)
print(book_obj)
# QuerySet [{a: 2}, {a: 1}, {a: 1}]F与Q查询
首先要导入模块
from django.db.models import Count, F, Q, Value
from django.db.models.functions import ConcatF查询
将所有书的价格增加100
# 将所有书的价格增加100
book_obj models.Book.objects.update(priceF(price)100)Q查询 # 原语句
# book_obj models.Book.objects.filter(price__gt400,price__lt700)
# Q语句
book_obj models.Book.objects.filter(Q(price__gt400),Q(price__lt700)
print(book_obj.values(title))
# QuerySet [{title: 水浒传}]获取价格大于400或小于700的数据
book_obj models.Book.objects.filter(Q(price__gt400) or Q(price__lt700))print(book_obj.values(title))book_obj models.Book.objects.filter(Q(price__gt400) | Q(price__lt700))print(book_obj.values(title))or和|的区别
使用 | 运算符时两个条件都会被考虑并返回满足任何一个条件的结果使用 or 运算符时只有第一个条件会被返回不会考虑第二个条件
Django开启事务
from django.db import transaction
try:# 开启事务with transaction.atomic():# 在事务开启前的保存点save_id transaction.savepoint()# 这部分代码会在事务中执行models.Book.objects.create(title三国演义,price1000)transaction.savepoint_commit(save_id)
except Exception as e:# 出错后回滚到save_id开始的地方transaction.savepoint_rollback(save_id)choices参数
gender_choice 是一个元组列表用于定义 Author 模型中 gender 字段的选项
class Author(models.Model):gender_choice ((0,男),(1,女),(2,保密))# 作者名name models.CharField(max_length32, uniqueTrue)# 年龄age models.IntegerField()# 性别gender models.IntegerField(choicesgender_choice,default2)if __name__ __main__:os.environ.setdefault(DJANGO_SETTINGS_MODULE, MyDJ.settings)import djangoimport datetimedjango.setup()from app01 import modelsfrom django.db import transactionauthor_obj models.Author.objects.get(id1)print(author_obj.gender)# 直接获取得到的是实际值2print(author_obj.gender_choice)# 获取关联的choice元组((0, 男), (1, 女), (2, 保密))print(author_obj.get_gender_display())# 获取展示给用户的值保密