каталог
Тестовая конфигурация Script
Режим 1:
# 如果想单独测试django中的某个文件,需要手动配置测试脚本(在你应用下的tests.py文件中)
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day55.settings")
import django
django.setup()
# 在测试脚本搭建完毕之后,才能导入django文件进行测试
from app01 import models
Вариант 2:
Новый прямой произвольное имя .py файлов, способ 1, выполненный с возможностью взять на линию.
Джанго ОРМ основные операции
CRUD
Во-первых, создать таблицу модели:
from django.db import models
# Create your models here.
class Books(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_date = models.DateField()
1. Добавить (создать ())
Добавить запись в базу данных
# 第一种 :
book_obj = models.Books.objects.create(title = '人性的弱点',price='172.44',publish_date='2008-08-08') # 日期格式可以直接写,也可以通过datetime模块生成一个年月日传进去
# 第二种:(利用对象的绑定方法)
book_obj = models.Books(title = '未来简史',price='399.44',publish_date='2008-08-09')
book_obj.save()
'''
返回的是对象本身
'''
2. Изменение (обновление ())
Таблица изменения некоторых полей в записи
res=models.Books.objects.filter(id=1).filter().filter().filter()...
'''
id可以写成pk,表示任意一张表的主键字段,我们不需要记自己建表时设置的主键字段的名字,直接写成pk=? 的形式,就more你是当前表的主键了;
返回的res是一个QuerySet对象,可以无限制的调用queryset对象,表示按照当前filter查询的结果继续按照你写的条件继续往下查询;
queryset对象还可以点query查看当前结果内部对应的sql语句
'''
res=models.Books.objects.filter(id=1)
print(res.query)
'''
SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_date` FROM `app01_books` WHERE `app01_books`.`id` = 1
'''
#方式1:
models.Books.objects.filter(id=1).update(price=88.88) # 当条件不存在时,filter空queryset对象,推荐使用filter进行查询。
# 方式2:
book_obj = models.Books.objects.get(pk=1) # 返回的是对象本身,get在条件不存在时会报错,不推荐使用这种方法做修改操作。
book_obj.price = 88.88
book_obj.save()
3. Удалить (Delete ())
Чтобы удалить запись в таблице
# 方式1:
models.Books.objects.filter(pk=3).delete()
# 方式2:
book_obj = models.Books.objects.get(pk=3)
book_obj.delete()
заявления SQL терминал печати Джанго
Для SQL Statement внутри вашего ОРМ запроса соответствующей печати в терминале, вы можете настроить следующий код в файле конфигурации settings.py проекта Django:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
13 Основные операции запроса
все()
Все запросы
res = models.Books.objects.all() # 查询所有 ,返回的结果QuerySet对象
'''
<QuerySet [<Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>, <Books: Books object>]>
'''
фильтр()
фильтр
res = models.Books.objects.filter(pk=2,title='活着') # 返回的结果QuerySet对象,支持传多个参数 并且是and关系
получить()
фильтр
res = models.Books.objects.get(title='活着',price = '99.9') # 获取的是数据对象本身,查询条件不存在报错,也可以传多个参数
'''
Books object
'''
первый()
QuerySet взять первый объект данных, возвращение нормального объекта данных
res = models.Books.objects.filter(title='活着').first()
прошлой()
QuerySet принимая последний объект данных, возвращение является нормальным объектом данных
res = models.Books.objects.filter(title='活着').last()
кол-()
Количество статистических данных, возвращает число (количество данных)
num = models.Books.objects.count()
значения()
Получает значение данных объекта, указанные в поле
# 按照指定条件查询
res = models.Books.objects.filter(pk=2).values('title','price')
print(res) # <QuerySet [{'title': '活着', 'price': Decimal('99.90')}]>
# 查所有
res = models.Books.objects.values('title','price') # 可以传多个参数, 返回的是QuerySet对象,列表套字典
'''
<QuerySet [{'title': '三国演义', 'price': Decimal('99.99')}, {'title': '活着', 'price': Decimal('99.90')}, {'title': '许三多卖血记', 'price': Decimal('199.88')}, {'title': '平凡的世界', 'price': Decimal('166.66')}, {'title': '富国论', 'price': Decimal('888.88')}, {'title': '鬼谷子', 'price': Decimal('35.55')}, {'title': '人性的弱点', 'price': Decimal('172.44')}, {'title': '人性的弱点', 'price': Decimal('172.44')}]>
'''
values_list ()
Получает значение данных объекта, указанные в поле
res = models.Books.objects.values_list('title','price') # 可以传多个参数, 返回的是QuerySet对象,列表套元组
'''
<QuerySet [('三国演义', Decimal('99.99')), ('活着', Decimal('99.90')), ('许三多卖血记', Decimal('199.88')), ('平凡的世界', Decimal('166.66')), ('富国论', Decimal('888.88')), ('鬼谷子', Decimal('35.55')), ('人性的弱点', Decimal('172.44')), ('人性的弱点', Decimal('172.44'))]>
'''
Сортировать по()
В соответствии с указанным полем сортировки
# 升序(两种写法)
res = models.Books.objects.order_by('price') # 默认是升序,返回的是queryset对象
res1 = models.Books.objects.all().order_by('price')
# 降序
res = models.Books.objects.order_by('-price') # 字段前面加负号
res = models.Books.objects.order_by('price').values('title','price')
print(res) # queryset对象可以继续通过点语法操作
'''
<QuerySet [{'title': '鬼谷子', 'price': Decimal('35.55')}, {'title': '活着', 'price': Decimal('99.90')}, {'title': '三国演义', 'price': Decimal('99.99')}, {'title': '平凡的世界', 'price': Decimal('166.66')}, {'title': '人性的弱点', 'price': Decimal('172.44')}, {'title': '人性的弱点', 'price': Decimal('172.44')}, {'title': '许三多卖血记', 'price': Decimal('199.88')}, {'title': '富国论', 'price': Decimal('888.88')}]>
'''
обратный()
В обратном порядке, то он должен быть заказан при этих обстоятельствах для того, чтобы полностью изменить
res = models.Books.objects.all().order_by('price').reverse()
'''
res = models.Books.objects.reverse().values('title','price') # 不排序的情况下返回值按照数据库的id顺序打印,没办法帮你颠倒
print(res)
res = models.Books.objects.all().order_by('price').reverse().values('title', 'price')
print(res)
"""
<QuerySet [{'title': '富国论', 'price': Decimal('888.88')}, {'title': '许三多卖血记', 'price': Decimal('199.88')}, {'title': '人性的弱点', 'price': Decimal('172.44')}, {'title': '人性的弱点', 'price': Decimal('172.44')}, {'title': '平凡的世界', 'price': Decimal('166.66')}, {'title': '三国演义', 'price': Decimal('99.99')}, {'title': '活着', 'price': Decimal('99.90')}, {'title': '鬼谷子', 'price': Decimal('35.55')}]>
"""
'''
исключить ()
Исключение, в соответствии с условиями данных указаны, кроме исключенных данных возвращают данные
# 方式1
res = models.Books.objects.all().exclude(title='三国演义') # queryset对象
# 方式2
res = models.Books.objects.exclude(title='三国演义')
существует()
Определите, какие результаты имеют значение возвращается результатом является логическим значением
res = models.Books.objects.filter(pk=1).exists()
print(res)
различны ()
В соответствии с условиями указанного веса
res = models.Books.objects.values('title','price').distinct() # 可以传入多个去重条件,把这多个条件都一样的数据剔除掉 返回的是一个queryset对象
Двухлинейное снижение запросов
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据;,也可以写成括号的形式
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
models.Tb1.objects.filter(name__contains="活") # 获取name字段包含"活"的
models.Tb1.objects.filter(name__icontains="活") # icontains大小写不敏感
models.Tb1.objects.filter(id__range=[1, 3]) # id范围是1到3的,顾头顾尾 ,也可以写成括号的形式
res = models.Tb1.objects.filter(title__endswith='活') # 以“活”开头的
res = models.Tb1.objects.filter(title__endswith='活') # 以“活”结尾的
date字段:
date字段可以通过在其后加__year,__month,__day等来获取date的特点部分数据
res=models.Tb1.objects.filter(publish_date='2008-08-08') # 指定年月日
res=models.Tb1.objects.filter(publish_date__lte='2002-03-28') # 日期小于等于2002-03-28的 也可以是lt,或者单独指定year,month,day
res=models.Tb1.objects.filter(publish_date__gte='2002-03-28') # 日期大于等于2002-03-28的 也可以是gt
res=models.Tb1.objects.filter(publish_date__year='2007') # 只指定年份
res=models.Tb1.objects.filter(publish_date__month='08') # 指定月份
res=models.Tb1.objects.filter(publish_date__day='29') # 指定某一天
models.Tb1.objects.filter(publish_date__week_day=2)
models.Tb1.objects.filter(publish_date__week_day__gte=2)
Таблица запросов
Для построения таблицы
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_date = models.DateField(auto_now_add=True)
stored = models.IntegerField(default=1000)
saled = models.IntegerField(default=1000)
def __str__(self): # 打印对象是触发,控制打印格式
return self.title
"""
auto_now:每次修改的数据的时候 都会自动更新修改书籍(展示最新的一次修改时间)
auto_now_add:当数据创建出来的时候 会自动将创建时间记录下来
"""
publish = models.ForeignKey(to='Publish') # 一对多关系,外键字段建在查询频率较高的一方
authors = models.ManyToManyField(to='Author') # 多对多关系,多对多字段建在查询频率较高的一方
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=32)
email = models.EmailField() # 对应到数据库的表当中是varchar类型,长度是254
author_detail = models.OneToOneField(to='AuthorDetail') # 一对一关系,一对多字段建在查询频率较高的一方
def __str__(self):
return self.name
class AuthorDetail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=64)
def __str__(self):
return self.addr
'''
模型表类建完以后,要使用数据库迁移命令,把表迁移到数据库当中,建表才算完毕
python3 manage.py makemigrations
python3 manage.py migrate
'''
Пропуска многих мест поиска изменения данных
Увеличение
# 方式1:
models.Book.objects.create(title='三国演义',price=222.33,publish_id=1) # 直接传表里面的实际字段和数据主键值
# 方式2:
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='红楼梦',price=444.33,publish=publish_obj) # 传虚拟字段 跟数据对象即可
изменение
# 方式1:
models.Book.objects.filter(pk=1).update(publish_id=2)
# 方式2:
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)
Удалить
models.Publish.objects.filter(pk=1).delete() # 默认级联删除,级联更新,这里删除id=1的出版社,出版社id=1的图书也都跟着删除
Пропуски многих ко многим поля поиска изменения данных
Увеличение (добавить)
book_obj = models.Book.objects.filter(pk=2).first()
# print(book_obj.publish) # Publish object
# print(book_obj.authors) # app01.Author.None 已经跨到第三张表了
# 方式1:(add支持传入多个,以逗号分开)
book_obj.authors.add(1) # 在第三张表里面给此书籍对象绑定一个author_id=1的作者
# 方式2:
author_obj1 = models.Author.objects.filter(pk=1).first()
author_obj2 = models.Author.objects.filter(pk=2).first()
book_obj.authors.add(author_obj1,author_obj2)
Краткое описание : метод добавления для добавления данных к третьей реляционной таблице, которая должна поддерживать цифровую передачу - «добавить (1,2); также поддерживает объекты проходят, добавить (author_obj, author_obj1), и оба могут быть множественным число.
Изменение (комплект)
book_obj = models.Book.objects.filter(pk=2).first()
# 方式1:
book_obj.authors.set((1,3))
book_obj.authors.set([1,])
# 方式2:
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.authors.set((author_obj,author_obj1))
Краткое описание : метод SET для изменения данных в таблице-многим, цифровая передача может быть объектом должны быть переданы, но один или несколько параметров , передаваемых в должен быть объектом итеративный, т.е. круглые скобки или скобки, внутри входящее число параметров вам нужно. пс: множество ((1,3)) , множество ((author_obj, author_obj1))
Удалить (удалить)
book_obj = models.Book.objects.filter(pk=2).first()
# 方式1:
book_obj.authors.remove(100)
book_obj.authors.remove(1,2)
# 方式2:
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.authors.remove(author_obj)
book_obj.authors.remove(author_obj,author_obj1)
Краткое описание : метод Remove , либо цифровая передача может быть подвержен износу, а также множество массовой поддержки не итерации; пс: удалить (1,2), удалить (author_obj, author_obj1)
Clear (прозрачный)
Удалить все записанные данные в третьей таблице
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.clear()
Кросс-таблица запросов
Плюсы и минусы запроса:
является объект запроса на основе таблицы по
полю отношений , в которых любой , кто связан с справочной таблицей является положительным ,
если поле отношения не в текущей таблице является обратным
Форвард запрос на поле: вперед - запрос, то запрос, когда существует множество данных, необходима точка .all (); пс: app01.Author.None, как только они видят результаты только нужно добавить .all () в
** обратный поиск по имени таблицы в нижнем регистре + _set: ** Тем не менее, во многих, многие ко многим обстоятельствам, нужно только добавить, в отношение один к одному, не показывать в нижнем регистре плюс _set.
Форвард запрос
1. Откройте книги первичный ключ для имени издателя 2
book_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.publish) # 出版社对象
print(book_obj.publish.name)
2. Запрос первичный ключ для имени автора книг 4
book_obj = models.Book.objects.filter(pk=4).first()
print(book_obj.authors) # app01.Author.None,跨入到了Author这张表中。
print(book_obj.authors.all()) # 一本书可能有多个作者,所以需要点.all() 返回的是queryset对象,列表内部是一个个的作者对象<QuerySet [<Author: Author object>, <Author: Author object>]>,这个是设置打印格式之后的显示:<QuerySet [<Author: zhang>, <Author: liu>]>,表示id=4 的书籍,有两个作者。
3. Запрос автор джейсон номер телефона
author_obj = models.Author.objects.filter(name='zhang').first()
print(author_obj.author_detail) # AuthorDetail object
print(author_obj.author_detail.phone)
Резюме: Форвард запрос, при получении запроса из Есть множество данных, потребность в точке .Все ();
пс: app01.Author.None, как только они видят результаты только нужно добавить .all () может
обратный просмотр
4. Запросы пресса Oriental Press Опубликованные книги
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set) # app01.Book.None
print(publish_obj.book_set.all())
5. Запрос автор Ясон написал книгу
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set) # app01.Book.None
print(author_obj.book_set.all()) # app01.Book.None
6. Номер телефона имя автора запроса 120
author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
print(author_detail_obj.author) # Author object 不需类名小写+_set,直接作者详情对象点类名(Author)小写即可
print(author_detail_obj.author.email) # 120qq.com
Кросс-таблица запроса основана на двойной линии падения
На основании запроса операционного стола с двойной линией снижения, сделать таблицу, состоящей из двух таблиц, использование Джанго ОРМ заявления может проверить информацию, которую вы хотите, сделать работу более кратким из.
1. Запрос книги для названия издательства 2 рк
# 方式1:正向查询
res = models.Book.objects.filter(pk=2).values('publish__name')
print(res) # <QuerySet [{'publish__name': '东方出版社'}]>
# 方式2:反向查询
res = models.Publish.objects.filter(book__pk=2).values('name')
print(res) # <QuerySet [{'name': '北方出版社'}]>
2. книги запросов, как имя автора и адрес электронной рк 2
# 方式1:正向查询
res =models.Book.objects.filter(pk=2).values('authors__name','authors__email')
print(res) # <QuerySet [{'authors__name': 'zhang', 'authors__email': '[email protected]'}, {'authors__name': 'liu', 'authors__email': '120qq.com'}]> 不需要像上面基本方法的跨表查询,这里不需要用点.all()
# 方式2:反向查询
res =models.Author.objects.filter(book__pk=2).values('name','email')
print(res) # <QuerySet [{'name': 'zhang', 'email': '[email protected]'}, {'name': 'liu', 'email': '120qq.com'}]>
Резюме : кто модели позже в базовой таблице Кто
3. Запрос автор Egon домашний адрес
# 方式1:正向查询
res=models.Author.objects.filter(name='egon').values('author_detail__addr')
print(res)
# 方式2:反向查询
res=models.AuthorDetail.objects.filter(author__name='egon').values('addr')
print(res)
4. Нажмите запрос название Oriental Press опубликовал книгу
# 方式1:正向查询
res = models.Publish.objects.filter(name='东方出版社').values('book__title')
print(res)
# 方式2:反向查询
res = models.Book.objects.filter(publish__name='东方出版社').values('title')
print(res)
5. Запрос является автором 2 книг рк номер телефона
# 方式1:正向查询
res=models.Book.objects.filter(pk=2).values('authors__author_detail__phone')
print(res)
# 方式2:反向查询
res=models.Author.objects.filter(book__pk=2).values('author_detail__phone')
print(res)
Агрегатная функция
1. Ключевое агрегат
2. Модули также необходимо импортировать
из django.db.models импорта Max, Min, Sum , Avg, граф
from django.db.models import Max, Min, Sum, Count, Avg
# 1.筛选出价格最高的书籍的
res = models.Book.objects.aggregate(mr = Max('price'))
print(res) # {'mr': Decimal('222.99')}
# 2.求书籍总价格
res = models.Book.objects.aggregate(sm = Sum('price'))
print(res) # {'sm': Decimal('600.58')}
# 3.求书籍平均价格
res = models.Book.objects.aggregate(av = Avg('price'))
print(res) # {'av': 150.145}
# 4.一起使用
res=models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('price'),Avg('price'))
print(res)
'''
{'price__max': Decimal('222.99'), 'price__min': Decimal('88.80'), 'price__sum': Decimal('600.58'), 'price__count': 4, 'price__avg': 150.145}
'''
Группировка запросов
1. Ключевое слово Аннотирование
2. Функции путем полимеризации
от django.db.models импорта Max, Min, Sum , Avg, граф
1. Количество статистики для каждой книги название и номер соответствующего автора
res=models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num')
print(res)
2. Нажмите статистические данные каждой книги продаются самые дешевые цены Нажмите Наименование Цена
res=models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
print(res)
3. Статистика больше, чем книги автора
res=models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num')
print(res)
4. Общая стоимость каждого запроса от общей стоимости названия книги
res=models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
print(res)
F Q запросы и запросы
Запрос F
- номер Проверить инвентаризации больше, чем количество проданных книг
from django.db.models import F,Q
res = models.Book.objects.filter(kun_cun__gt = F('mai_cun')).values('title') # 后面的条件是来自于数据库的其他字段值
print(res) # <QuerySet [{'title': '天龙八部'}]>
2. Стоимость всех книг выросли 100
models.Book.objects.all().update(price=F('price') + 100)
3. Имена всех задней частью книги всех слов «модель взрыва» суффикс
from django.db.models.functions import Concat
from django.db.models import Value
ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
Q запрос
1. Название книги запрос о Троецарствие книг или инвентарным номером в 500
from django.db.models import Q
res = models.Book.objects.filter(title='三国演义',kun_cun=500) # and关系
res = models.Book.objects.filter(title='三国演义',kun_cun=500) # and关系
res = models.Book.objects.filter(Q(title='三国演义'),Q(kun_cun=500))# Q包裹之后逗号还是and关系
res = models.Book.objects.filter(Q(title='三国演义') | Q(kun_cun=500)) # |就是or的关系
res = models.Book.objects.filter(~Q(title='三国演义')|Q(kun_cun=500)) # ~就是not关系
print(res)
Q объектов Продвинутое использование
q = Q()
q.connector = 'or' # 默认是and 可以改成or
q.children.append(('title','三国演义'))
q.children.append(('kun_cun__gt',500))
res = models.Book.objects.filter(~q) # 取反
print(res)
from django.db import transaction
with transaction.atomic():
# 在缩进的代码中书写数据库操作
# 该缩进内的所有代码 都是一个事务
pass
ORM поля и параметры
orm字段及参数
CharField varchar
IntegerField int
BigIntegerField bigint
EmailField varchar(254)
DateField
DateTimeField
auto_now:每次修改数据的时候 都会自动将当前修改时间更新上去 实时更新
auto_now_add:在创建数据的时候 会将当前时间自动记录 之后不会自动修改 除非你人为修改
AutoField auto_increment
BooleanField 布尔值
该字段在存储的时候 你只需要传布尔值True或False
它会自动存成1/0
TextField 专门用来存大段文本
FileField 专门用来文件路径 '/etc/data/a.txt'
upload_to = '/etc/data'
给该字段传值的时候 直接传文件对象
会自动将文件对象保存到upload_to后面指定的文件路径中
然后将路径保存到数据库
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
Пользовательские поля гольца
# 如何自定义字段类型
class MyCharField(models.Field):
def __init__(self,max_length,*args,**kwargs):
self.max_length = max_length
# 重新调用父类的方法
super().__init__(max_length=max_length,*args,**kwargs)
def db_type(self, connection):
return 'char(%s)'%self.max_length