Python_Django系列_2.模型
目录
前言
不做作,还是代码实在
一、Django的数据库
Django 模型使用自带的 ORM。
对象关系映射(Object Relational Mapping,简称 ORM )
Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。
这里就介绍,一些关键。得记录在案
1. 常用的代码命令行
python manage.py migrate # 创建表结构
python manage.py makemigrations app # 让 Django 知道我们在我们的模型有一些变更
python manage.py migrate app# 创建表结构
2. Setting.py对数据库的修改
DATABASES = {
'default':
{
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'NAME': 'handsome', # 数据库名称
'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1
'PORT': 3306, # 端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库密码
}
}
3. Django 使用 pymysql 模块连接 mysql 数据库:
# 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置
import pymysql
pymysql.install_as_MySQLdb()
4.使用模型,必须要创建一个 app
django-admin.py startapp app
5.学习连接
6.定义模型类对应的表名
class Meta:
db_table = '图书表'
7.on_delete参数
django2.0+版本配置模型类外键关系必须指定on_delete参数
● 级联删除:models.CASCADE 当关联表中的数据删除时,该外键也删除
● 置空:models.SET_NULL 当关联表中的数据删除时,该外键置空,当然,你的这个外键字段得允许为空,null=True
● 设置默认值:models.SET_DEFAULT 删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
8.字段类型
类型 | 描述 |
---|---|
AutoField | 主键,自动增长的IntegerField,可以不用指定,自动创建 |
CharField | 字符串 |
BooleanField | 布尔字段 |
DateField | 日期字段 |
DateTimeField | 日期字段 |
SmallIntegerField | 小整数 |
DecimalField | 十进制浮点数。参数(max_digits,decimal_places) |
FileField | 上传文件字段 |
ImageField | 主键,自动增长的IntegerField,可以不用指定,自动创建 |
OneToOneField | 一对一 |
ForeignKey | 一对多 |
ManyToManyField | 多对多 |
字段参数 | 描述 |
---|---|
verbose_name | verbose_name='奥特曼' 用于指定名称 |
primary_key | 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。 |
choices | choices=status其中status等于一个元祖 |
unique | unique=true 如果为True, 这个字段在表中必须有唯一值,默认值是False。 |
db_index | 若值为True, 则在表中会为此字段创建索引,默认值是False。 |
db_column | 字段的名称,如果未指定,则使用我们定义的Field对应数据库中的字段名称。 |
max_length | 最大长度 |
max_digits | 最大位数 |
decimal_places | 小数点后位数 |
on_delete | models.CASCADE,models.SET_NULL ,models.SET_DEFAULT |
blank | 如果为True,则该字段允许为空白,默认值是False。 |
null | 如果为True,表示允许为空,默认值是False。 |
9.模型管理器
当没有为模型类定义管理器时,Django会为每一个模型类生成一个名为objects的管理器,自定义管理器后,Django不再生成默认管理器objects。
books = models.Manager()
二、查询的API
通过模型类.objects属性可以调用如下函数
函数名 | 返回值 | 说明 |
---|---|---|
get | 只有一条;是一个模型类对象 | 如果查到多条数据或查询不到数据,都会抛出异常 |
all | 所有数据;是QuerySet类型 | |
filter | 满足条件数据;是QuerySet类型 | |
filter模糊查询 | contains;endswith;isnull;in ;gt;gte;lt;lte | |
exclude | 不满足条件数据;返回值是QuerySet类型 | |
order_by | 对查询结果进行排序;是QuerySet类型 | |
values,values_list | 返回查询对象的值;是QuerySet类型 | values : queryset类型的列表中是字典;values_list : queryset类型的列表中是元组 |
first | 匹配到的第一个对象; 是一个模型类对象 | |
exists | 查询的数据是否存在; 是一个布尔值True 或False | |
count | 统计满足条件数据的数目; 是一个整形 | |
aggregate | 对查询结果进行聚合操作; | 使用前需先导入聚合类: from django.db.models import Sum,Count,Max,Min,Avg |
#关联查询
#由一类(Book)查询多类(Publish)
#方法一:一类的对象.多类名小写_set.all()
b = models.Book.objects.get(username='admin')
b.Publish_set.all()
#<QuerySet [<Publish: 华山出版社>]>
#方法二:多类名.objects.filter(关联属性__一类属性名__条件名)
models.Publish.objects.filter(user__username='admin')
#<QuerySet [<Publish: 华山出版社>]>
#由多类(Publish)查询一类(Book)
#多类的对象.关联属性
#方法一:多类的对象.主键
h = models.Publish.objects.get(title='华山出版社')
h.name
#<Book: '红楼梦'>
#方法二:一类名.objects.filter(多类名小写__多类属性名__条件名)
models.Book.objects.filter(Publish__title='华山出版社')
#<QuerySet [<Book: '红楼梦'>]>
#[自关联地区上下区](https://www.yuque.com/keep_running/python/ctw9z5)
三、模型类的例子
from django.db import models
# 表结构
# 书籍表 Book:title 、 price 、 pub_date 、 publish(外键,多对一) 、 authors(多对多)
# 出版社表 Publish:name 、 city 、 email
# 作者表 Author:name 、 age 、 an_detail(一对一)
# 作者详情表 AuthorDetail:gender 、 tel 、 addr 、 birthday
# Create your models here.
class Book(models.Model):
id = models.AutoField(primary_key=True) # id 会自动导入,也可以手动设置
title = models.CharField(max_length=32) # 书籍名称
price = models.DecimalField(max_digits=5, decimal_places=2) # 价格
pub_date = models.DateField() # 出版时间
publish = models.ForeignKey('Publish', on_delete=models.CASCADE) # 一对多通过外键
authors=models.ManyToManyField('Author')
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=64)
email = models.EmailField()
class Author(models.Model):
name=models.CharField(max_length=32)
age=models.SmallIntegerField()
an_detail=models.OneToOneField('AuthorDetail',on_delete=models.CASCADE)
class AuthorDetail(models.Model):
gender_choices=((0,'女'),(1,'男'),(2,'保密'))
gender=models.SmallIntegerField(choices=gender_choices)
tel=models.CharField(max_length=32)
addr=models.CharField(max_length=64)
birthday=models.DateField()
四、代码温习(增删查改)
1.逻辑层view.py
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from django.views.decorators.csrf import csrf_exempt
from First import models
def tr(request):
Text = "我的尝试!!"
return HttpResponse(Text)
def home(request):
a = "这是一个表单"
b = [1, 2, 3]
return render(request, 'home.html', context={"a": a, "b": b})
def search(request):
request.encoding = 'UTF-8'
# if request.path==''
#
print(request.path)
if 'q' in request.GET and request.GET['q']:
msg = "你搜索的内容:" + request.GET['q']
else:
msg = '你提交了空表单!'
return render(request, 'getform.html', {"msg": msg})
def searchpost(request):
# res={}
# if request.POST:
# res['result']=request.POST.get('textq')
# print(res['result'])#在控制台看结果
# print(request.path)
return render(request, 'bookform.html')
# 书籍的添加
def add_book(request):
msg = ""
if request.POST:
title = request.POST.get('title')
price = request.POST.get('price')
publish = request.POST.get('publish')
pub_date = request.POST.get('pub_date')
# 这是第一种方法
# book=models.books(title=title,price=price,publish=publish,pub_date=pub_date)
# book.save()#进行保存!!
# 这是第二章方法**推荐
book = models.books.objects.create(title=title, price=price, publish=publish, pub_date=pub_date)
print(book, book.price)
msg = '保存成功!!'
return render(request, 'home.html', {'msg': msg})
# 书籍的查询
def search_book(request):
# 查询所有
# book=models.books.objects.all()
# 查询筛选返回的是 QuerySet 类型数据,类似于 list,使用循环提取出来
# 只能使用等于号 = ,__in __range 用于读取区间,= 号后面为列表 。
# __gt __gte __lt __lte大于号 ,= 号后面为数字。
# __contains __icontains 不区分大小写的包含__startswith 以指定字符开头,__startswith 以指定字符开头,= 号后面为字符串
# __year __month __day 是 DateField 数据类型的年份,= 号后面为数字2008。
# book=models.books.objects.filter(pk=4)#pk是主键primary key=3,==id=3
# exclude() 方法用于查询不符合条件的数据。
# get() 方法用于查询符合条件的返回模型类的对象符合条件的对象只能为一个,
# 如果符合筛选条件的对象超过了一个或者没有一个都会抛出错误。
# order_by() 方法用于对查询结果进行排序。降序为在字段前面加个负号 -。
# reverse() 方法用于对查询结果进行反转。
# count() 方法用于查询数据的数量返回的数据是整数。
# first() 方法返回第一条数据返回的数据是模型类的对象也可以用索引下标 [0]。
# last() 方法返回最后一条数据返回的数据是模型类的对象不能用索引下标 [-1]
# exists() 方法用于判断查询的结果 QuerySet 列表里是否有数据
# 返回的数据类型是布尔,有为 true,没有为 false。
# 注意:判断的数据类型只能为 QuerySet 类型数据,不能为Book.objects.count()整型和models.Book.objects模型类的对象。
# values() 方法用于查询部分字段的数据。
# 不是模型类的对象,而是一个可迭代的字典序列, 字典 里的键是字段,值是数据。
# values_list() 方法用于查询部分字段的数据。
# 不是模型类的对象,而是一个个元组,元组 0.1里放的是查询字段对应的数据。
# distinct() 方法用于对数据进行去重# 对模型类的对象去重没有意义,因为每个对象都是一个不一样的存在
book = models.books.objects.filter(price__range=[100, 500]) # pk是主键primary key=3,==id=3
for i in book:
print(i.price)
print(book)
msg = '查询结果成功!!'
return render(request, 'home.html', {'msg': msg})
# 书籍的删除
def delete_book(request):
#books=models.Book.objects.all().delete() # 删除成功
# 方式一:使用模型类的
# 对象.delete()。
#books=models.Book.objects.filter(pk=8).first().delete()
# 返回值:元组,第一个元素为受影响的行数。
# 方式二:使用 QuerySet 类型数据.delete()(推荐)
# 返回值:元组,第一个元素为受影响的行数。
book = models.books.objects.filter(pk__in=[1, 2]).delete() # pk是主键primary key=3,==id=3
# for i in book:
# print(i.price)
print(book)
msg = '删除成功!!'
return render(request, 'home.html', {'msg': msg})
# 书籍的修改
def update_book(request):
#update_or_create#如果数据库内没有该数据,那么新增,如果有,则更新
# 方式一:
# 模型类的对象.属性 = 更改的属性值
# 模型类的对象.save()
# 方式二:QuerySet
# 类型数据.update(字段名=更改的数据)(推荐)
# 返回值:整数,受影响的行数
book = models.books.objects.filter(pk__in=[3,4]).update(price=167) # QuerySet 类型数据
# for i in book:
# print(i.price)
# book.price=145
# book.save()
print(book)
msg = '修改成功!!'
return render(request, 'home.html', {'msg': msg})
2.页面层
主页面home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>不拘一格降人才</title>
</head>
<body>
<button><a href="{% url 'getform' %}">填空get表单</a></button><br>
<button><a href="{% url 'postform' %}">书籍页面</a></button>
<p>表单结果:{{ msg }}</p>
</body>
</html>
get请求页面getform.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p>{{ a }}</p>
<p>{{ b.0 }}</p>
<form action="{% url 'getform' %}" method="get">
<input type="text" name="q">
<input type="submit" value="搜索">
</form>
<p>{{ msg }}</p>
</body>
</html>
书籍页面bookform.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>哈哈哈</title>
</head>
<body>
<div align="left">
<form action="{% url 'add_book' %}" method="post">
{% csrf_token %}
书名:<input type="text" name="title"><br>
价格:<input type="text" name="price"><br>
出版社名:<input type="text" name="publish"><br>
出版日期:<input type="date" name="pub_date"><br>
<input type="submit" value="添加书籍">
</form>
</div>
<button><a href="{% url 'home' %}">返回首页</a></button><br>
<button><a href="{% url 'search_book' %}">进行查询</a></button>
<button><a href="{% url 'delete_book' %}">进行删除</a></button>
<button><a href="{% url 'update_book' %}">进行修改</a></button>
</body>
</html>
3.模型层
models.py
from django.db import models
# Create your models here.
class books(models.Model):
id=models.AutoField(primary_key=True)#id 会自动导入,也可以手动设置
title=models.CharField(max_length=32)#书籍名称
price=models.DecimalField(max_digits=5,decimal_places=2)#价格
publish=models.CharField(max_length=32)#出版社名称
pub_date=models.DateField()#出版时间
4.路由设置
- 总路由urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('First.urls'))
]
- 分路由urls.py
"""djangoProject1 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from First import views
urlpatterns = [
path('admin/', admin.site.urls),
path('tr/', views.tr, name='try'),
#首页
path('', views.home, name='home'),
#POST和GET表单
path('getform/', views.search, name='getform'),
path('postform/', views.searchpost, name='postform'),
#数据库BOOK操作
path('add_book/',views.add_book,name='add_book'),#增加
path('search_book/',views.search_book,name='search_book'),#查询
path('delete_book/',views.delete_book,name='delete_book'),#删除
path('update_book/',views.update_book,name='update_book')#修改
]
总结
总之今天是受益匪浅。。。