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.分组和命名分组

  1. 分组

    url(r'^blog/(\d{4})/([1-9]{2})/$', views.blog, name='blog')

  2. 命名分组

    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')
  1. 外键的操作

    外键字段为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='太亮的产后护理')

posted @ 2018-12-06 19:49  SuraSun  阅读(73)  评论(0)    收藏  举报