当前位置:K88软件开发文章中心网站服务器框架django → 文章内容

Django 模型高级进阶

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-25 14:19:20

ass Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=50) # ... objects = models.Manager() # The default manager. dahl_objects = DahlBookManager() # The Dahl-specific manager.在这个示例模型中,Book.objects.all()返回了数据库中的所有书本,而Book.dahl_objects.all()只返回了一本. 注意我们明确地将objects设置成manager的实例,因为如果我们不这么做,那么唯一可用的manager就将是dah1_objects。当然,由于get_query_set()返回的是一个QuerySet对象,所以我们可以使用filter(),exclude()和其他一切QuerySet的方法。 像这些语法都是正确的:Book.dahl_objects.all()Book.dahl_objects.filter(title='Matilda')Book.dahl_objects.count()这个例子也指出了其他有趣的技术: 在同一个模型中使用多个manager。 只要你愿意,你可以为你的模型添加多个manager()实例。 这是一个为模型添加通用滤器的简单方法。例如:class MaleManager(models.Manager): def get_query_set(self): return super(MaleManager, self).get_query_set().filter(sex='M')class FemaleManager(models.Manager): def get_query_set(self): return super(FemaleManager, self).get_query_set().filter(sex='F')class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female'))) people = models.Manager() men = MaleManager() women = FemaleManager()这个例子允许你执行Person.men.all() ,Person.women.all() ,Person.people.all() 查询,生成你想要的结果。如果你使用自定义的Manager对象,请注意,Django遇到的第一个Manager(以它在模型中被定义的位置为准)会有一个特殊状态。 Django将会把第一个Manager 定义为默认Manager ,Django的许多部分(但是不包括admin应用)将会明确地为模型使用这个manager。 结论是,你应该小心地选择你的默认manager。因为覆盖get_query_set() 了,你可能接受到一个无用的返回对像,你必须避免这种情况。模型方法为了给你的对像添加一个行级功能,那就定义一个自定义方法。 有鉴于manager经常被用来用一些整表操作(table-wide),模型方法应该只对特殊模型实例起作用。这是一项在模型的一个地方集中业务逻辑的技术。最好用例子来解释一下。 这个模型有一些自定义方法:from django.contrib.localflavor.us.models import USStateFieldfrom django.db import modelsclass Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() address = models.CharField(max_length=100) city = models.CharField(max_length=50) state = USStateField() # Yes, this is U.S.-centric... def baby_boomer_status(self): "Returns the person's baby-boomer status." import datetime if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31): return "Baby boomer" if self.birth_date < datetime.date(1945, 8, 1): return "Pre-boomer" return "Post-boomer" def is_midwestern(self): "Returns True if this person is from the Midwest." return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO') def _get_full_name(self): "Returns the person's full name." return u'%s %s' % (self.first_name, self.last_name) full_name = property(_get_full_name)例子中的最后一个方法是一个property。 想了解更多关于属性的信息请访问http://www.python.org/download/releases/2.2/descrintro/#property这是用法的实例:>>> p = Person.objects.get(first_name='Barack', last_name='Obama')>>> p.birth_datedatetime.date(1961, 8, 4)>>> p.baby_boomer_status()'Baby boomer'>>> p.is_midwestern()True>>> p.full_name # Note this isn't a method -- it's treated as an attributeu'Barack Obama'执行原始SQL查询有时候你会发现Django数据库API带给你的也只有这么多,那你可以为你的数据库写一些自定义SQL查询。 你可以通过导入django.db.connection对像来轻松实现,它代表当前数据库连接。 要使用它,需要通过connection.cursor()得到一个游标对像。 然后,使用cursor.execute(sql, [params])来执行SQL语句,使用cursor.fetchone()或者cursor.fetchall()来返回记录集。 例如:>>> from django.db import connection>>> cursor = connection.cursor()>>> cursor.execute("""... SELECT DISTINCT first_name... FROM people_person... WHERE last_name = %s""", ['Lennon'])>>> row = cursor.fetchone()>>> print row['John']connection和cursor几乎实现了标准Python DB-API,你可以访问 http://www.python.org/peps/pep-0249.html http://www.python.org/peps/pep-0249.html>__来获取更多信息。 如果你对Python DB-API不熟悉,请注意在cursor.execute() 的SQL语句中使用“%s” ,而不要在SQL内直接添加参数。 如果你使用这项技术,数据库基础库将会自动添加引号,同时在必要的情况下转意你的参数。不要把你的视图代码和django.db.connection语句混杂在一起,把它们放在自定义模型或者自定义manager方法中是个不错的主意。 比如,上面的例子可以被整合成一个自定义manager方法,就像这样:from django.db import connection, modelsclass PersonManager(models.Manager): def first_names(self, last_name): cursor = connection.cursor() cursor.execute(""" SELECT DISTINCT first_name FROM people_person WHERE last_name = %s""", [last_name]) return [row[0] for row in cursor.fetchone()]class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) objects = PersonManager()然后这样使用:>>> Person.objects.first_names('Lennon')['John', 'Cynthia']接下来做什么?在下一章 我们将讲解Django的通用视图框架,使用它创建常见的网站可以节省时间。

上一页  [1] [2] [3] 


Django 模型高级进阶