簡體   English   中英

在Django中重用filter()查詢集

[英]Reuse filter() queryset in Django

我想編寫一次過濾器,然后在各處重復使用,我該怎么辦?

例如:有一個帶有標記field Student模型。 我想編寫一個過濾器來吸引非研究生( flag=0 )。 但是在許多視圖和函數中,我們需要列出非研究生,我很懶惰,不想在這些視圖和函數中一次又一次地編寫過濾器,因為這將使維護源代碼變得很困難。

我可以在學生模型中使用meta嗎? 我沒有找到任何與過濾器相關的meta選項。 還是可以編寫一個函數來過濾學生模型? 在我看來,模型中的函數僅適用於一個Student對象,而不適用於列表。

您可以使用自定義管理器使內容保持干燥並增強可讀性(顯式命名的過濾器總是比拖動復雜的過濾器更好)

class GraduateManager(models.Manager):
    def get_queryset(self):
        return super(GraduateManager, self).get_queryset().filter(graduated=True)

class UndergraduateManager(models.Manager):
    def get_queryset(self):
        return super(Undergraduate, self).get_queryset().filter(graduated=False)

class Student(models.Model):
    graduated = BooleanField()

    graduates = GraduateManager()
    undergraduates = UndergraduateManager()

要使用它,您將獲得一個常規查詢集,可以根據需要進行操作

Student.graduates.all(), or .filter(), or .count() etc

參考https://docs.djangoproject.com/en/1.8/topics/db/managers/#modifying-initial-manager-querysets

現在,使用自定義QuerySet和QuerySet.as_manager()是最好的解決方案。 Dabapps的Jamie Matthews在他的博客文章構建更高級別的查詢API中詳細討論了可重用的過濾器:使用Django ORM的正確方法

“直接在視圖中使用Django的低級ORM查詢方法(通常)是一種反模式”
—傑米·馬修斯(Jamie Matthews)

該博客文章是在Django獲得QuerySet的.as_manager()方法之前編寫的。

我現在使用類似這樣的東西(基於當前接受的答案 ):

class StudentQuerySet(models.query.QuerySet):
    def graduate(self):
        return self.filter(graduated=True)

    def undergraduate(self):
        return self.filter(graduated=False)

class Student(models.Model):
    graduated = BooleanField()

    objects = StudentQuerySet.as_manager()

在其他更復雜的情況下,能夠在自定義查詢集中定義復雜的過濾器很有用,因為這樣實現時過濾器是可鏈接的。

如果您希望其他模型中的相關管理器可以使用此功能(即,如果您有另一個模型引用了Student模型並且正在使用otherinstance.student_set.all() ),請參見Django:使用管理器進行相關對象訪問 簡而言之,這樣做:

class Student(models.Model):
    graduated = BooleanField()

    objects = StudentQuerySet.as_manager()
    objects.use_for_related_fields = True

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM