[英]Django (DRF) ManyToMany field choices / limit
使用 Django REST 框架 我想知道是否可以將 model 上ManyToMany
字段的選擇/選項限制為特定的QuerySet
?
使用下面的模型(向下滾動查看模型),我很好奇是否可以在 model 的定義中定義此限制,以實現以下目標:
# Having the following Employee instance
emp = Employee(...)
# Should return only the instances with value 'case' in EmployeeSubstitute.type field
emp.substitute_case.all()
# Should return only the instances with value 'phone' in EmployeeSubstitute.type field
emp.substitute_phone.all()
楷模:
class Employee(models.Model):
substitute_case = models.ManyToMany(through=EmployeeSubstitute, ...)
substitute_phone = models.ManyToMany(through=EmployeeSubstitute, ...)
class EmployeeSubstitute(models.Model):
from = models.ForeignKey(Employee, ...)
to = models.ForeignKey(Employee, ...)
type = models.CharField(choices=..., ...) # choose between type 'case' and 'phone'
我看到有limit_choices_to
參數,但這不是我要找的,因為它只會影響使用 ModelForm 或管理員時顯示的選項。
好吧, ManyToManyField
返回相關對象和文檔state
默認情況下,Django在訪問相關對象(即choice.question)時使用Model._base_manager manager class的一個實例,而不是相關object上的_default_manager。這是因為Django需要882828即使檢索到相關的29否則會被默認管理器過濾掉(因此無法訪問)。
如果正常的基礎管理器 class (django.db.models.Manager) 不適合您的情況,您可以通過設置 Meta.base_manager_name 告訴 Django 使用哪個 class。
在查詢相關模型或訪問一對多或多對多關系時,不使用基礎管理器。 例如,如果教程中的問題 model 有一個 deleted 字段和一個過濾掉 deleted=True 實例的基本管理器,則像 Choice.objects.filter(question__name__startswith='What') 這樣的查詢集將包括與已刪除問題相關的選項。
所以如果我沒看錯的話,不,這是不可能的。
當您在ManyToManyField
中進行查詢並through
時,Django 抱怨您應該through
model 而不是“父級”運行這些查詢。 我在文檔中找不到它,但我記得看過幾次。
substitute_case
和substitute_phone
是屬於 substitute 的東西,是它的類型。 因此,只需這樣做而不是在Employee
中創建這些列。
from django.db import models
class SubstituteTypes(models.TextChoices):
case = "case", "case"
phone = "phone", "phone"
class EmployeeSubstituteQueryset(models.QuerySet):
def from_employee(self, e):
return self.filter(_from=e)
def case(self):
return self.filter(type=SubstituteTypes.case)
def phone(self):
return self.filter(type=SubstituteTypes.phone)
class Employee(models.Model):
substitute = models.ManyToManyField(through='EmployeeSubstitute', to='self')
class EmployeeSubstitute(models.Model):
_from = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='a')
to = models.ForeignKey(Employee, on_delete=models.PROTECT, related_name='b')
type = models.CharField(choices=SubstituteTypes.choices, max_length=5, db_index=True)
objects = EmployeeSubstituteQueryset.as_manager()
然后,一旦你得到你的emp
object (或只有它的 id),你就可以做
EmployeeSubstitute.objects.from_employee(emp).case().all()
這是在 Django 哲學中設計的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.