Django进阶——模型的高级用法
2018-02-04 18:03
573 查看
定义模型:
一、访问外键值
二、ForeignKey 字段反向访问
三、访问多对多值
四、管理器
在 Book.objects.all() 语句中,objects 是个特殊的属性,即模型的管理器(manager),我们通过它查询数据库。
-
模型的管理器是 Django 模型用于执行数据库查询的对象。一个 Django 模型至少有一个管理器, 而且可以自定义管理器,定制访问数据库的方式。自定义管理器可能出于两方面的原因:添加额外的管理器 方法和(或)修改管理器返回的 QuerySet。
添加管理器
使用
五、修改模型默认方法
六、执行原始 SQL查询
把查询中的字段映射到模型字段上
索引和切片
执行条件查询
使用 params 参数能完全避免 SQL 注入攻击。这是一种常见的漏洞,攻击者能设法向数据库中 注入任意的 SQL。如果使用字符串插值,迟早有一天你会变成 SQL 注入的牺牲者。记住,一 定要使用 params 参数,这样便能得到保护。
七、直接执行自定义的 SQL
①获取连接:django.db.connection
②获取游标对象:connection.cursor()
③执行SQL:cur- sor.execute(sql, [params])
④获取结果: cursor.fetchone() 或 cursor.fetchall()
示例:
from django.db import models 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 Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() def __str__(self): return '%s %s' % (self.first_name, self.last_name) class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() def __str__(self): return self.title
一、访问外键值
访问 ForeignKey 类型的字段时,得到的是相关的模型对象。
>>>b = Book.objects.get(id=50) >>>b.publisher <Publisher: Apress Publishing> >>>b.publisher.website 'http://www.apress.com/'
二、ForeignKey 字段反向访问
book_set 就是一个 QuerySet 对象。book_set 属性是生成的:把模型名的小写形式与 _set 连在一起。
>>> p = Publisher.objects.get(name='Apress Publishing') >>> p.book_set.all() [<Book: The Django Book>, <Book: Dive Into Python>, ...]
三、访问多对多值
查看一本的的作者,得到的结果是 QuerySet 值
>>> b = Book.objects.get(id=50) >>> b.authors.all() [<Author: Adrian Holovaty>, <Author: Jacob Kaplan-Moss>] >>> b.authors.filter(first_name='Adrian') [<Author: Adrian Holovaty>] >>> b.authors.filter(first_name='Adam')
查看一位作者撰写的所有图书,使用 author.book_set
>>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty') >>> a.book_set.all() [<Book: The Django Book>, <Book: Adrian's Other Book>]
四、管理器
在 Book.objects.all() 语句中,objects 是个特殊的属性,即模型的管理器(manager),我们通过它查询数据库。
-
模型的管理器是 Django 模型用于执行数据库查询的对象。一个 Django 模型至少有一个管理器, 而且可以自定义管理器,定制访问数据库的方式。自定义管理器可能出于两方面的原因:添加额外的管理器 方法和(或)修改管理器返回的 QuerySet。
添加管理器
为 Book 模型添加一个管理器方法 title_count(),它的参数是一个关键字,返回书名中 包含关键字的图书数量
from django.db import models # ... Author 和 Publisher 模型省略了 ... #定义第一个管理器 class BookManager(models.Manager): def title_count(self, keyword): return self.filter(title__icontains=keyword).count() #定义第二个管理器 class DahlBookManager(models.Manager): def get_queryset(self): return super(DahlBookManager,self).get_queryset().filter(author='Roald Dahl') class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() num_pages = models.IntegerField(blank=True, null=True) objects = models.Manager() # 默认的管理器 dahl_objects = DahlBookManager() # 专门查询 Dahl 的管理器 def __str__(self): return self.title
使用
Book.objects.title_count('django') Book.dahl_objects.all() Book.dahl_objects.filter(title='Matilda') Book.dahl_objects.count()
五、修改模型默认方法
一系列封装数据库行为的模型方法有时也需要自定义。尤其是 save() 和 delete(),经常需要修改它们的 运作方式。
from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() #覆盖默认的save方法 def save(self, *args, **kwargs): do_something() super(Blog, self).save(*args, **kwargs) # 调用“真正的”save () 方法 do_something_else()
六、执行原始 SQL查询
Manager.raw(raw_query, params=None, translations=None) #模型 class Person(models.Model): ... #使用原始查询('myapp_person'表示myapp下的Person模型) for p in Person.objects.raw('SELECT * FROM myapp_person'): ...
把查询中的字段映射到模型字段上
方式一: Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person') 方式二: Person.objects.raw('''SELECT first AS first_name,last AS last_name,bd AS birth_date,pk AS id,FROM some_other_table''') 方式三: name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'} Person.objects.raw('SELECT * FROM some_other_table',translations=name_map)
索引和切片
first_person = Person.objects.raw('SELECT * FROM myapp_person LIMIT 1')[0]
执行条件查询
正确写法: Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname]) 错误写法: query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
使用 params 参数能完全避免 SQL 注入攻击。这是一种常见的漏洞,攻击者能设法向数据库中 注入任意的 SQL。如果使用字符串插值,迟早有一天你会变成 SQL 注入的牺牲者。记住,一 定要使用 params 参数,这样便能得到保护。
七、直接执行自定义的 SQL
①获取连接:django.db.connection
②获取游标对象:connection.cursor()
③执行SQL:cur- sor.execute(sql, [params])
④获取结果: cursor.fetchone() 或 cursor.fetchall()
示例:
from django.db import connection def my_custom_sql(self): cursor = connection.cursor() cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz]) cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz]) row = cursor.fetchone() return row
使用多个数据库时,可以使用 django.db.connections 获取指定数据库的连接(和游标)。django.db.connec-tions 是一个类似字典的对象,可以使用别名取回指定连接:
from django.db import connections cursor = connections['my_db_alias'].cursor()
相关文章推荐
- Python Django进阶教程(三)(模型的高级用法)
- Django------ Advanced Models 模型高级进阶 2012.09.02
- Django笔记 —— 模型高级进阶
- django book学习笔记――模型高级进阶
- 20121030 The django book 笔记 数据模型高级进阶
- 【django 学习笔记】09-数据模型高级进阶
- Django------The template 模版高级进阶1 2012.08.30
- thinkphp5 数据库和模型详解 之4 模型数据处理(核心)和高级用法
- django1.8读书笔记模型高级进阶
- Django框架学习-Templates进阶用法
- Django 模型系统(model)&ORM--进阶
- django book学习笔记――模板高级进阶
- Python Django进阶教程(一)(高级视图和URL配置)
- grep与egrep用法从基础到高级进阶
- Django------ The template 模版高级进阶2 2012.08.31
- (9)Django框架学习-Templates进阶用法--上
- (10)Django框架学习-Templates进阶用法--中
- Django框架学习-Templates进阶用法
- Django笔记 —— 模板高级进阶
- django教程--model教程之查询高级用法