6.视图与数据库的交互
6.1 django操作数据库
注意:如果查询不到数据,报错
6.1.1 get方法
返回一个数据对象
# 查询id=1的用户信息,get方法如果查询不到数据,会报错
ret1 = UserInfo.objects.get(id=1)
ret2 = UserInfo.objects.get(pk=1)
print(ret1,ret2)
6.1.2 all方法
查询当前表中所有的数据
# 查询当前表中所有的数据
# 返回的是一个列表
ret3 = UserInfo.objects.all()
print(ret3)
# 查询当前表中有多少个列表
ret4 = UserInfo.objects.count()
print(ret4)
6.1.3 count方法
查询当前表中的数据 的数量
# 查询当前表中有多少个列表
ret4 = UserInfo.objects.count()
print(ret4)
6.1.4 filter方法
条件过滤
# 查询id=7的用户
ret5 = UserInfo.objects.get(id=3)
ret6 = UserInfo.objects.filter(id__exact=3)
print("ret5",ret5,"ret6",ret6[0])
-
模版的属性__excat
:等于ret7 = UserInfo.objects.filter(name__exact='龙哥') print(ret7)
-
模版的属性__contains
:包含# 名字中包含u的数据 ret8 = UserInfo.objects.filter(name__contains='u') # 不区分大小写 ret9 = UserInfo.objects.filter(name__icontains='u') print(ret8) print('ret9:',ret9)
-
模版的属性__in
:在……之中# 查询id在1 3 5 7 9的人 ret10 = UserInfo.objects.filter(id__in=[1,3,5,7,8]) print(ret10)
-
模版的属性__gt
:大于模版的属性__gte
:大于等于模版的属性__lt
:小于模版的属性__lte
:小于等于# 查询id大于3的人 ret11 = UserInfo.objects.filter(id__gt=3) ret12 = UserInfo.objects.filter(id__gte=3) print(ret11) print("ret12",ret12) # 查询id小于3的人 ret13 = UserInfo.objects.filter(id__lt=3) print("ret13:",ret13)
6.2不想使用ORM模块
6.2.1 使用django自带的
from django.db import connection
cur = connection.cursor()
count = cur.execute('select * from user_userinfo where id > %s;',(3,))
# count = cur.execute('select * from user_userinfo where id > %s;',[3])
print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
print(count)
for obj in cur.fetchall():
print(obj)
6.2.2 使用pymysql
import pymysql
con = pymysql.connect(host='localhost',
user = 'root',
password = 'mysql',
database = 'pai0805',
port = 3306,
charset = 'utf8'
)
cur = con.cursor()
ret1_num = cur.execute('select * from user_userinfo')
print(ret1_num)
xxx = cur.fetchall()
6.2.3 使用sqlalchemy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine("mysql+pymysql://root:mysql@127.0.0.1:3306/pai0805", max_overflow=5)
Base = declarative_base()
class Users(Base):
__tablename__ = 'user_userinfo'
id = Column(Integer, primary_key=True)
name = Column(String(10,collation='NOCASE'))
age = Column(Integer())
phone = Column(String(11))
def __str__(self):
return self.name
Session = sessionmaker(bind=engine)
session = Session()
print('#$%$#%#$#*)&)%#@*&%(#*@')
ret1 = session.query(Users.id, Users.name,Users.age,Users.phone).all()
print(ret1)
6.3 F与Q对象
6.3.1 F对象是用来两个属性之间的对比
比如:选取数据库,表中第一个字段比第二个字段大的
# F():解决属性与属性的对比
# 查找阅读量大于销量
ret1 = BookInfo.objects.filter(count__gt=F('seltcount'))
print(ret1)
# 查找销量是两倍阅读量的书
ret2 = BookInfo.objects.filter(seltcount__exact=2*F('count'))
print(ret2)
# ret2_1 = BookInfo.objects.filter(seltcount=2*F('count'))
# print("ret2_2:",ret2_1)
# 查找销量时两倍阅读量的书,并且阅读量不等于0
ret3 = BookInfo.objects.filter(seltcount__exact=2*F('count'),seltcount__gt=0)
print(ret3)
# 使用多个filter()过滤器,类似where条件中的and
ret4 = BookInfo.objects.filter(seltcount__exact=2*F('count')).filter(seltcount__gt=0)
print("ret3_2",ret4)
6.3.2 Q对象用来表示各个关系的与或非的操作,& | ~
Q对象:实现逻辑操作
# 找出销量大于0的书籍
ret5 = BookInfo.objects.filter(seltcount__gt=0)
ret5 = BookInfo.objects.filter(Q(seltcount__gt=0))
print("ret5:",ret5)
# 查找销量大于0,或小于0的
ret6 = BookInfo.objects.filter(Q(seltcount__gt=0)|Q(count__lt=0))
ret7 = BookInfo.objects.filter(Q(seltcount__gt=0)&Q(count__lt=0))
print(ret6)
print('ret7',ret7)
# 查找销量不等于0的书籍
ret8 = BookInfo.objects.filter(~Q(seltcount__exact=0))
print("ret8:",ret8)
6.4 聚合函数
def aggregate(self, *args, **kwargs):
"""
Returns a dictionary containing the calculations (aggregation)
over the current queryset
If args is present the expression is passed as a kwarg using
the Aggregate object's default alias.
"""
'''
返回一个字典,其中包含当前查询集的计算(聚合)
如果存在args,则使用Aggregate对象的默认别名将表达式作为kwarg传递。
'''
from django.db.models import Sum,Avg,Count,Max,Min,StdDev #标准偏差
# 求阅读量的总和
ret9 = BookInfo.objects.aggregate(Sum('count'))
print(ret9)
# 查询书籍,并且以销量排序
ret10 = BookInfo.objects.all().order_by('seltcount')
print("ret10",ret10)
6.5 一对多,多对一,多对多
6.5.1 一对多
由少的一方访问多的一方 由一到多
比如:一本书 对应 多个人物
try:
# 1.先查询出需查询的书籍
book = BookInfo.objects.get(bookname='西游记')
print(book)
print(type(book))
# 2.通过书籍查找该书中的人物
# 格式:少的模型实例对象.多的模型类(小写)info_set
peoples = book.personinfo_set.all()
print(peoples)
except Exception as e:
print(e)
6.5.2 多对一
比如:通过书里的人物,找到这一本书
try:
# 1.查找到这个人物
person1 = PersonInfo.objects.get(pname='孙悟空')
# 2.找到这本书
# 格式:少的模型实例对象.外键属性
print(person1.book)
print(type(person1.book))
# 获取 这本书的id (两种方法)
print(person1.book_id)
print(person1.book.id)
except Exception as e:
print(e)
6.6 关联过滤查询
定义:以当前模型类对象为主要查询数据的依据,在查询当前对象的时候,以它所关联的表为过滤条件。
另一张表的字段数据作为过滤条件,来查询当前表的数据。
# 查询人物为孙悟空的书籍
# 1.用sql语句
# SELECT * FROM bookinfo WHERE id=(SELECT book_id FROM personinfo WHERE pname='孙悟空')
# 2.利用已有知识
# 2.1 找到人物的对象
person_id2 = PersonInfo.objects.get(pname='孙悟空')
print(person_id2.id)
# 2.2 查找这本书
bookinfo2 = BookInfo.objects.get(id=person_id2.id)
print(bookinfo2)
# 3. 简化
# 格式:关联模型类的小写__属性名__条件筛选运算符=值
book_obj2 = BookInfo.objects.filter(personinfo__pname__exact='孙悟空')
print(book_obj2)
例子2:
# todo 图书销量大于0的人
person_objs = PersonInfo.objects.filter(book__seltcount__gt=0)
print(person_objs)
# 查询id不等于1的
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
obj2 = BookInfo.objects.exclude(id__exact=1).order_by('publictime')
print(obj2)
6.6 重写manager类与相关的方法
6.6.1 新建一个bookmanager
class BookManager(models.Manager):
'''重写父类,改写管理器类'''
pass
6.6.2 在模型中添加管理器
实例化
class BookInfo(models.Model):
new_objects = BookManager()
6.6.3 重写方法all()
:可以查询逻辑删除的数据
class BookManager(models.Manager):
'''重写父类,改写管理器类'''
def all(self):
return super().filter(is_delete=False)
6.6.4 模仿原生create()
方法,创建新的mycreate()
# 原生的create
def create(self, **kwargs):
"""
Creates a new object with the given kwargs, saving it to the database
and returning the created object.
"""
obj = self.model(**kwargs)
self._for_write = True
obj.save(force_insert=True, using=self.db)
return obj
class BookManager(models.Manager):
'''重写父类,改写管理器类'''
def all(self):
return super().filter(is_delete=False)
def mycreate(self,bookname,publictime):
'''自定义创建一个新的模型对象'''
print('这是进行定义的创建方法')
obj = self.model()
obj.bookname=bookname
obj.publictime=publictime
obj.save()
return obj
# book = BookInfo()
# book.bookname='下写的'
# book.publictime='2019-09-25'
# book.save()
使用
BookInfo.new_objects.mycreate('新瞎写的','2019-1-1')
6.7 视图类
在view.py
中定义视图类
from django.views.generic import View
class ShowUsers(View):
def get(self,request):
return HttpResponse('这是Get方法')
def post(self,request):
return HttpResponse('这是Post方法')
在urls.py
中添加路径
urlpatterns = [
url(r'^users/$',views.ShowUsers.as_view()),
]