【问题标题】:How does Django know which model manager to use?Django 如何知道使用哪个模型管理器?
【发布时间】:2017-06-11 03:40:41
【问题描述】:

所以我有兴趣在 Django 项目中使用下面的示例代码,但在尝试了解如何明确调用模型管理器时感到困惑。

class AuthorManager(models.Manager):
    def get_queryset(self):
        return super(AuthorManager,    self).get_queryset().filter(role='A')

class EditorManager(models.Manager):
    def get_queryset(self):
        return super(EditorManager, self).get_queryset().filter(role='E')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
    people = models.Manager()
    authors = AuthorManager()
    editors = EditorManager()

我知道视图调用模型,模型调用模型管理器,但这让我有点困惑。我可以指定哪个视图调用哪个管理器,或者模型是否通过其他方式隐式处理?

【问题讨论】:

    标签: django django-models django-database


    【解决方案1】:

    根据documentation,您可以使用Person.authors.get_querysetPerson.editor.get_queryset 从您的视图中调用任一模型管理器。此外,您可以将数据传回给任一经理。例如:

    在视图中:

    data = {
        'first_name' : request.POST['first_name'],
        'last_name' :request.POST['last_name'],
        'email' : request.POST['email'],
      }
    author = Person.authors.new_author(data)
    editor = Person.editor.new_editor(data)
    

    上面的“author”/“editor”变量将成为您的模型传回的任何内容。

    显然,您希望在管理器中定义新方法。例如

    在模型中:

    class AuthorManager(models.Manager):
        def new_author(self):
            Person.authors.create(...)
    
    class EditorManager(models.Manager):
        def new_editor(self):
            Person.editors.create(...)
    

    您可以选择让您的模型将您需要的任何用户信息传回您的视图。

    【讨论】:

    • 所以在我的 PersonViewSet 中我可以调用 Person.authors.filter(name='eric') 或类似的东西吗?这是我与如何真正利用它的主要脱节。
    • 是的,完全可以,您可以在视图中进行简单的数据库调用,但对于更复杂的逻辑,如验证等,您希望将其推回模型。
    • 任何你可以推回模型的工作,都有一个 Manger 句柄,例如创建一个带有验证的用户。最好将尽可能多的逻辑分配给模型(以及视图之外)。
    • 你能举一个简单的例子来说明我如何将逻辑推回模型,然后从视图中调用它们吗?我认为意见的唯一目的是接受请求并做出回应。但这涉及到执行逻辑的视图。我希望看到您的方式得到实施。
    • 根据经验,您希望拥有瘦控制器、胖模型。因此,如果您的网站上有一个表单,并且希望在将每个字段提交到数据库之前确保每个字段都有一个值(一定数量的字符或电子邮件正则表达式),那么您将需要进行验证。这可能会占用多行代码,因此您将验证放在模型管理器中,然后,例如,如果验证未得到满足,让管理器将错误消息发送回您的视图。清楚吗?
    【解决方案2】:
    class PersonQuerySet(models.QuerySet):
        def authors(self):
            return self.filter(role='A')
    
        def editors(self):
            return self.filter(role='E')
    
    class Person(models.Model):
            first_name = models.CharField(max_length=50)
            last_name = models.CharField(max_length=50)
            role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
            people = models.Manager()
            objects = PersonQuerySet.as_manager()
    

    获取作者和编辑:

    authors = Person.objects.authors()
    editors = Person.objects.editors()
    

    【讨论】:

      猜你喜欢
      • 2010-12-05
      • 2013-08-17
      • 2021-04-05
      • 2012-09-06
      • 2012-04-14
      • 2021-10-04
      • 2021-09-09
      • 2019-05-24
      • 1970-01-01
      相关资源
      最近更新 更多