我想建立一个新的相关字段类型。这是一个简单的例子:
class CustomQuerySet(QuerySet):
def current(self):
return self.filter(invalid_date__isnull=True)
class CustomManager(Manager):
def get_query_set(self):
return CustomQuerySet(self.model, using=self._db)
def current(self):
return self.get_query_set().current()
class Item(models.Model):
objects = CustomManager()
row_id = models.IntegerField(primary_key=True)
id = models.IntegerField()
name = models.CharField(max_length=100)
change_date = models.DateTimeField(auto_now_add=True)
invalid_date = models.DateTimeField(null=True, blank=True)
class Collection(models.Model):
item = MultipleRelatedField(Item, related_field='id', related_name='collections')
name = models.CharField(max_length=100)
鉴于c = Collection()
:
c.item
应返回相当于Item.objects.filter(id=c.item_id)
。Item.objects.filter(collections__name='SomeName')
应按预期工作。Collection.objects.filter(item__name='OtherName', item__invalid_date__isnull=True)
应按预期工作。我意识到这可以用ManyToManyField
实现,但我不想手动添加/删除项目对象到c.item。我不需要连接表,因为c.item总是使用单个id值,它不是Collection上的主键。并且c.item
可能/不包含具有不同id值的项目对象。
我知道这可能需要继承django.db.models.fields.related.ForeignRelatedObjectsDescriptor
和/或django.db.models.fields.related.ForeignObject
(或者可能是ManyToMany等价物)。
答案 0 :(得分:1)
在我看来,您真正想要的是根据A
中字段的值,从模型B
生成针对其他模型A
的查询集的自动方式。
我怀疑最终,将该查询集作为A
上的字段值返回并不是最好的解决方案 - 这实际上违背了ORM的内容并且会使其变得困难,例如,在管理员或其他常见地方使用该模型。
相反,最好从Django如何处理具有choices
集的字段中获取一个想法:在模型类中自动生成一个返回派生信息的方法,这样如果你的模型有一个字段: / p>
item = MultipleRelatedField(Item, related_field='id', related_name='collections')
你会自动获得一个像get_item_queryset
这样的方法来返回你指定的查询集。
要构建它,您可能希望子类化现有字段(IntegerField
可能是一个很好的起点),然后覆盖__init__
方法(接受其他参数)和{ {1}}方法(将生成新方法)。你可以看到the choices
-derived get_FIELD_display
method here获得灵感的地方。