zoukankan      html  css  js  c++  java
  • Django Manager Queryset

    Django Manager Queryset

    1.ORM objects

    我们使用 Django ORM进行数据库操作时,默认使用的Manager 对象是objects,每个Django模型默认拥有一个。

    类似如下情况:

    from django.db import models
    
    
    class Student(models.Model):
        name=models.CharField(max_length=128)
        ...
        objects=models.Manger()
        def get_student_by_name(self, name):
            return self.objects.get(name=name)
    

    2.自定义Manager

    class StudentManager(models.Manager):
        def  get_student_by_name(self, name):
            return self.filter(name=name)
        def get_student_by_id(self, id):
            return self.filter(id=id)
    
    class Student(models.Model):
        ...
        modify = StudentManager()
    

    ORM语句

    models.Student.modify.get_student_by_name(name)
    

    当我们只使用自定义Manager对象查询时,各个自定义方法是不能够链接的

    例如下面语法是错误的(此处的语句没有意义,仅用来说明问题)

    models.Student.modify.get_student_by_name(name=name).get_student_by_id(id=id)
    

    3.自定义queryset

    
    class StudentManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset().filetr(...)
        
        def  get_student_by_name(self, name):
            return self.filter(name=name)
        
        def get_student_by_id(self, id):
            return self.filter(id=id)
    
    class Student(models.Model):
        ...
        modify = StudentManager()
    

    此时,我们使用如下语句查询会得到我们想要的QuerySet对象

    models.student.modify.all()
    

    对于三多提出的不能链接的问题此处就可以使用如下实例解决:

    class StudentQuerySet(models.QuerySet):
    	def get_queryset(self):
            super().get_queryset().filetr(...)
            
    	def  get_student_by_name(self, name):
            return self.filter(name=name)
        
        def get_student_by_id(self, id):
            return self.filter(id=id)
    
        
    class StudentManager(models.Manager):
        def get_queryset(self):
            return StudentQuerySet.get_queryset()
        
        def  get_student_by_name(self, name):
            return self.filter(name=name)
        
        def get_student_by_id(self, id):
            return self.filter(id=id)
    
    class Student(models.Model):
        ...
        modify = StudentManager()
    

    此时,如下语句是没有问题的:

    models.Student.modify.get_student_by_name(name=name).get_student_by_id(id=id)
    

    此时,我们会发现QuerySet 和Manager 有重复代码。

    使用as_manager解决

    如下,我们不直接实例化StudentManager类

    class Student(models.Model):
        ...
        modify = StudentQuerySet.as_manager()
    

    4.总结

    Django 官网指出,

    You can use a custom Manager in a particular model by extending the base Manager class and instantiating your custom Manager in your model.

    There are two reasons you might want to customize a Manager: to add extra Manager methods, and/or to modify the initial QuerySet the Manager returns.

    Adding extra Manager methods is the preferred way to add “table-level” functionality to your models. (For “row-level” functionality – i.e., functions that act on a single instance of a model object – use Model methods, not custom Manager methods.)

    A custom Manager method can return anything you want. It doesn’t have to return a QuerySet.

    关于使 models 肥胖(胖模型瘦控制器)还是抽离(业务逻辑应当在Django的什么位置)的讨论不是本文的目的。有情趣可以参考如下链接

    Where to put business logic in Django

    Django Best Practices — Refactoring Django Fat Models

    个人觉得业务逻辑存放于何处取决于你们团队最初的设计 DDD MVC 等。当然在不同设计模式下也有不同实现方式,有机会我们在共同学习分享!

  • 相关阅读:
    【习题整理】分块+莫队(未完待续)
    【bzoj4198】【Noi2015】荷马史诗
    【bzoj2006】【NOI2015】超级钢琴
    【bzoj1029】【JSOI2007】建筑抢修
    【bzoj1483】【HNOI2009】梦幻布丁
    【bzoj4195】【NOI2015】程序自动分析
    Rearrangement inequality
    hdu1047
    hdu1046
    hdu1045
  • 原文地址:https://www.cnblogs.com/9527mwz/p/13588723.html
Copyright © 2011-2022 走看看