Day65--django之ORM
day65
内容回顾
1.路由
from django.conf.urls import url
from app02 import views
urlpatterns = [
url(r'^home/$', views.home, name='home'),
]
2.正则
^ $ | [0-9]{} \d + ? * .
3.include
# 导入app01和app02下的urls,namespace命名空间,为了区分app01和app02下的同名url,防止覆盖
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'app01/',include('app01.urls',namespace='app01')),
url(r'app02/',include('app02.urls',namespace='app02'))
]
4.分组和命名分组
-
分组
url(r'^blog/(\d{4})/([1-9]{2})/$', views.blog, name='blog')
-
命名分组
url(r'^blog/(?P
\d{4})/(?P [1-9]{2})/$', views.blog, name='blog') 命名分组后, 在views中接收参数是要按照关键字接收关键字参数,如此时接收 request, year,month
5.url的命名和反向解析
url(r'^home/$', views.home, name='home'),
url(r'^blog/(?P<year>\d{4})/(?P<month>[1-9]{2})/$', views.blog, name='blog')
视图中:
from django.urls import reverse
reverse('home') ——》 ‘/app01/home/’
reverse('blog',args=(2018,12)) ——》‘/app01/blog/2018/12’
reverse('blog',kwargs={'year':'2008','month':12}) ——》‘/app01/blog/2008/12’
模板中:
{% url 'home' %}
{% url 'blog' '2018' '12' %}
{% url 'blog' month='12' year='2008' %}
6.namespace
reverse('app01:home') ——》 ‘/app01/home/’
{% url 'app01:home' %}
今日内容
1.字段和字段的参数
常用的:
AutoField
IntegerField
BooleanField
CharField
TextField
DateTimeField
DecimalField
更多字段,见官网 https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types
自定义char类型的字段类
class MyCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return 'char(%s)' % self.max_length
# 自定义char类型的使用
class Person(models.Model):
phone = MyCharField(max_length=11, )
字段参数
class Person(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, db_column='username',verbose_name='姓名')
# null数据库层面可以为空, blank表单层面可以为空
age = models.IntegerField(null=True, blank=True,verbose_name='年龄')
# 每次新增数据的时候自动把当前时间添加进来
# birth = models.DateTimeField(auto_now_add=True)
# 每次修改的时候都会保存当前时间
birth = models.DateTimeField(auto_now=True)
# auto_now_add和auto_now还有default是互斥的
phone = MyCharField(max_length=11)
# choices里面放可迭代对象,元组列表都可以,第一个元素放表里存的真实数据,后面是代表的意思
# 如果不加choices, 会出现一个gender的勾选框,是否勾选
gender = models.BooleanField(choices=((0,'男'),(1,'女')))
class Meta:
# 数据库中生成的表名, 默认 app名称_下划线+类名
db_table = 'person'
# admin中显示的表名称
verbose_name = '个人信息'
verbose_name_plural = '所有用户信息'
# 按照id字段升序排序
ordering = ('id',)
###################################
primary_key=True # 设置主键
max_length=32 # 设置最大字符长度
db_column='username' # 设置字段名
verbose_name='姓名' #设置在superuser中显示的字段名
null=True # 数据库中的数据可以为空
blank=True # 超级用户界面中的 数据可以为空
auto_now_add=True # 新增的时候保存当前的时间
auto_now=True # 每次修改的时候保存当前的时间
choices=((0, '男'), (1, '女'))
2.查询的方法(13个) 见代码
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
import django
django.setup()
from app01 import models
# all() 获取所有的数据 对象列表
ret = models.Person.objects.all()
# filter() 获取所有满足条件的所有对象 对象列表
ret = models.Person.objects.filter(id=1)
# get() 获取一个对象 没有或者是多个的时候报错
ret = models.Person.objects.get(id=1)
# exclude 获取不满足条件的所有对象 对象列表
ret = models.Person.objects.exclude(id=1)
# values 获取对象的字段名和值 [ {},{} ]
# 不指定字段名 获取所有字段的名和值
# 指定字段名 获取指定字段的名和值
ret = models.Person.objects.all().values('name','id')
# for i in ret:
# print(i,type(i))
# values_list 获取对象的值 [ (),() ]
# 不指定字段名 获取所有字段的值
# 指定字段名 获取指定字段值
ret = models.Person.objects.all().values_list('id','name')
# for i in ret:
# print(i,type(i))
# order_by 排序 默认升序 加 - 降序 指定多个进行排序,
ret = models.Person.objects.all().order_by('age','id')
# reverse() 给已经排好序的结果倒叙排序
ret = models.Person.objects.all().order_by('age','id').reverse()
ret = models.Person.objects.all().reverse()
# distinct() 去重
# count 计数
ret = models.Person.objects.all().count()
# first() last() 取第一个 最后一个对象,列表为空返回none,不会报错
ret = models.Person.objects.filter(id=100).first()
# exists() 判断数据是否存在
ret = models.Person.objects.filter(id=1).exists()
print(ret)
"""
返回结果是对象列表 8 后面可以继续加filter,get等等, 见下一个代码块
all()
filter()
exclude()
order_by()
reverse()
values()
values_list()
distinct()
返回结果是对象 3
get()
first()
last()
返回布尔值 1
exists()
返回数字 1
count()
"""
print(models.Book.objects.filter(pk__gt=1))
print(models.Book.objects.filter(pk__gt=1).filter(pk=3))
3.单表的双下划线 见代码
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
import django
django.setup()
from app01 import models
ret = models.Person.objects.filter(id=1)
ret = models.Person.objects.filter(id__gt=1) # greater than
ret = models.Person.objects.filter(id__gte=1) # greater than equal
ret = models.Person.objects.filter(id__lt=3) # less than
ret = models.Person.objects.filter(id__lte=3) # less than equal
ret = models.Person.objects.filter(id__gt=1, id__lt=3)
ret = models.Person.objects.filter(id__range=[1, 3]) # 范围 左右都包含
ret = models.Person.objects.filter(id__in=[1, 3]) # id在列表中
ret = models.Person.objects.filter(name__contains='alex') # 包含 like
ret = models.Person.objects.filter(name__icontains='alex') # 包含 like i = ignore 忽略大小写
ret = models.Person.objects.filter(name__startswith='a') # 以什么开头
ret = models.Person.objects.filter(name__istartswith='a') # 以什么开头 忽略大小写
ret = models.Person.objects.filter(name__endswith='x') # 以什么结尾
ret = models.Person.objects.filter(name__iendswith='X') # 以什么结尾 忽略大小写
ret = models.Person.objects.filter(birth__year=2018)
ret = models.Person.objects.filter(birth__contains='2018-12')
print(ret)
4.外键的操作
正向查询:
book_obj.publisher 关联的对象
反向查
不指定related_name
pub_obj.book_set 管理对象
pub_obj.book_set.all()
指定related_name = ‘books’
pub_obj.books 管理对象
基于字段的查询
# 基于字段的查询
# ret = models.Book.objects.filter(publisher__name='老男孩出版社')
# 不指定related_name
# ret = models.Publisher.objects.filter(book__title='太亮教开车')
# 指定related_name
# ret = models.Publisher.objects.filter(books__title='太亮教开车')
# 指定related_query_name='book'
# ret = models.Publisher.objects.filter(book__title='太亮教开车')
related_name 和 related_query_name
如果没有指定related_query_name, 只指定了related_name=books, 那么 models.Publisher.books.filter(books__title) 也可以查询书名. 如果两个同时指定了, 在查询的时候只能用related_query_name
class Publisher(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=32)
publisher = models.ForeignKey('Publisher', related_name='books', related_query_name='book',null=True)
def __str__(self):
return self.title
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField('Book',related_name='authors')
# 外键字段可以为null 才有remove和clear 只能写对象
pub_obj = models.Publisher.objects.get(id=1)
# pub_obj.books.remove(models.Book.objects.get(id=1))
# pub_obj.books.clear() #删除这个出版社对象在图书列表中的所有记录
5.多对多的操作 见代码
多对多操作里面可以写id和对象.
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_practice.settings")
import django
django.setup()
from app01 import models
# 基于对象的查询
# 正向
author_obj = models.Author.objects.get(id=2)
#
# print(author_obj.books,type(author_obj.books))
# print(author_obj.books.all())
# 反向
book_obj = models.Book.objects.get(id=1)
# 不指定related_name='authors'
# print(book_obj.author_set.all())
# 指定related_name='authors'
# print(book_obj.authors.all())
# set 设置多对多关系
# author_obj.books.set([]) # 相当于清空关联对象
# author_obj.books.set([1,2,3]) # 要关联对象的ID [ 对象的id,对象的id]
# author_obj.books.set(models.Book.objects.all()) # 要关联对象 [ 对象,对象]
# add 添加多对多的关系
# author_obj.books.add(1) # 要关联对象的ID
# author_obj.books.add(models.Book.objects.get(id=2)) # 要关联对象
# remove() 删除多对多的关系
# author_obj.books.remove(1) # 要关联对象的id
# author_obj.books.remove(models.Book.objects.get(id=2)) # 要关联对象
# clear() # 清空当前对象的多对多的关系
# author_obj.books.clear() # 效果和author_obj.books.set([])一样
# create()
# 新建书籍对象,同时关联当前出版社对象
# author_obj.books.create(title='太亮教抛光',)
book_obj.authors.create(name='alex')
-
外键的操作
外键字段为null=True时 才有remove和clear, 里面只能写对象.
由于是多对一, add操作相当于替换,里面也是只能写对象.
外键字段
将id为1的出版社与id为5的书籍关联, 相当于把id为5的书籍的出版社关联id替换成1. add(对象)
models.Publisher.objects.get(pk=1).books.add(models.Book.objects.get(pk=5))
remove(对象)解除关联
pub_obj.books.remove(models.Book.objects.get(id=1))
clear(对象)将当前出版社对象与书籍的关联关系清空
pub_obj.books.clear()
创建书籍并与当前出版社对象关联
pub_obj.books.create(title='太亮的产后护理')

浙公网安备 33010602011771号