Skip to content

Latest commit

 

History

History
111 lines (93 loc) · 6.59 KB

模型层.md

File metadata and controls

111 lines (93 loc) · 6.59 KB

给模型添加__str__()方法,让模型能够在shell中展示结果

查找数据的时候,django用的不是select *, 而是把所有字段列出来

详细分析 Publisher.objects.all() 这行代码: • 首先,Publisher 是我们定义的模型。这没什么可意外的,想查找数据就应该使用相应的模型。 • 然后,访问 objects 属性。这叫管理器(manager),在第 9 章详述。现在,你只需知道,管理器负责 所有“表层”数据操作,包括(最重要的)数据查询。所有模型都自动获得一个 objects 管理器,需要 查询模型实例时都要使用它。 • 最后,调用 all() 方法。这是 objects 管理器的一个方法,返回数据库中的所有行。虽然返回的对象 看似一个列表,但其实是一个查询集合(QuerySet)——表示数据库中一系列行的对象。附录 C 将详 细说明查询集合。本章都将把它视作它所模仿的列表。

过滤数据

可以传多个参数给filter方法 Publisher.objects.filter(name='Apress',state_province='CA') <==> select * from books_publisher where name = 'Apress' and state_province='CA'

查找操作默认使用sql的 = 操作符精准查找

模糊查找

以下返回均为QuerySet对象 Publisher.objects.filter(name__contains="press") <==> select * from books_publisher where name like '%press%' 还支持其他查找类型:有icontains(不区分大小写的like), startswith和endswith,以及range(sql的between语句)

检索单个对象

只返回一个对象,查询不到的时候会抛出Publisher.DoesNotExist异常 Publisher.objects.get(name='aaa')

排序数据

如果需要反向排序,方法是在字段名称前面加上“-”(减号) 如果想根据多个字段排序(以第一个字段排不出顺序时使用第二个字段),提供多个参数: order_by("name","address")

虽然 order_by() 有一定的灵活性,但是每次都调用它相当繁琐。多数时候,我们始终使用同一个字段排序。 此时,可以在模型中指定默认排序: class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() def str(self): return self.name class Meta: ordering = ['name']

改,单个多个都可以

Publisher.objects.filter(id='11').update(name='aaaa')

update() 方法可以在任何 QuerySet 对象上调用,这意味着可以通过它批量编辑多个记录。 下述代码把每个 Publisher 记录的 country 列都由 'U.S.A.' 改为 'USA': Publisher.objects.all().update(country='USA')

删除一个对象,只需在对象上调用 delete() 方法: 删除多个Publisher.objects.filter(country='USA').delete() 为了防止不小心把表中的数据都删除,想删除表中的一切数据时,Django 要求必须显式调 用 all() 方法。例如,下述代码无效: 如果只想删除部分数据,无需调用 all() 方法。下面再以前面的一个示例为例: >>> Publisher.objects.filter(country='USA').delete

把字段设为可选的

email = models.EmailField(blank=True) class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True)

把日期和数值字段设为可选的

为日期和数值字段设定 blank=True 时经常遇到问题,这背后涉及很多知识。SQL 使用是一个特殊的值表示空 值——NULL。它的意思是“未知”或“无效”,或者其他情境中的特定意思。在 SQL 中,NULL 与空字符串不是一 回事,就像 Python 对象 None 不是空字符串("")一样。 例如 Django 管理后台,当你留空字符字段时,Django 插入数据库的是空字符串 (而不是 NULL 值)。但是,对空字符串不是有效值的数据库列类型(如日期、时间和数字)来说,这样处理不行。如果把空字符 串插入日期或整数列,数据库有可能报错——这取决于你用的数据库。(PostgreSQL 严格,遇到这种情况时 抛出异常;MySQL 可能允许这么做,也可能不允许,根据版本、时间和月相而定。)

class Book(models.Model):
        title = models.CharField(max_length=100)
        authors = models.ManyToManyField(Author)
        publisher = models.ForeignKey(Publisher)
        publication_date = models.DateField(blank=True, null=True) #允许该字段为空

添加 null=True 比添加 blank=True 复杂,因为前者修改了数据库的语义,即修改了 CREATE TABLE 语句,把 publication_date 字段的 NOT NULL 删掉了。为了完成修改,我们要更新数据库。

class Author(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=40)
        email = models.EmailField(blank=True, verbose_name='e-mail')

修改admin.py

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book
class AuthorAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'email')
        admin.site.register(Publisher) 
        admin.site.register(Author, AuthorAdmin) 
        admin.site.register(Book)

修改 admin.site.register() 调用,在 Author 后面添加 AuthorAdmin。你可以把这行代码理解为“以 AuthorAdmin 中的选项注册 Author 模型” admin.site.register() 函数的第二个参数可选,其值是一个 ModelAdmin 子类。如果不指定第二个参数(Publisher 和 Book 模型就是这样),Django 使用默认选项 注册模型。

search_fields添加搜索框

通过设置search_fields,能够搜索所选field的

class AuthorAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'email')
        search_fields = ('first_name', 'last_name')

添加日期过滤器

list_filter = ('publication_date',) 显示一个日期层级导航栏:date_hierarchy = 'publication_date'

选择想展示的字段的顺序

fields 选项还有一个作用:排除特定的字段,禁止编辑。只需去掉想排除的字段即可。如果你只相信管理员 有能力编辑数据的某些部分,或者某些字段由外部的自动化流程修改,就可以这么做。

多对多

filter_horizontal = ('authors',)水平的两个文本框 filter_vertical 垂直的两个文本框 raw_id_fields = ('publisher',)各个字段在管理后台中显示为简单的文本输入框(),而不是 菜单