如何使用相关对象的自定义管理器?
我有一个自定义管理器。我想用它来处理相关的对象。我在文档中找到了use_for_related_fields。但它不工作,我用它的方式:如何使用相关对象的自定义管理器?
class RandomQueryset(models.query.QuerySet):
def randomize(self):
count = self.count()
random_index = random.randint(0, count - 1)
return self.all()[random_index]
class RandomManager(models.Manager):
use_for_related_fields = True
def get_query_set(self):
return RandomQueryset(self.model, using=self._db)
def randomize(self):
return self.get_query_set().randomize()
我用了一个模型:
>>> post = PostPages.default_manager.filter(image_gallery__isnull=False).distinct().randomize()
并试图做同样的M2M相关的对象:
>>> post.image_gallery.randomize()
出现错误:
AttributeError: 'ManyRelatedManager' object has no attribute 'randomize'
是有没有可能像我一样使用自定义管理器?如果是这样,你如何使它工作?
编辑
我的模型:
class ShivaImage(models.Model, ImageResizing):
image = models.ImageField(upload_to='img')
slide_show = models.BooleanField()
title = models.CharField(max_length=100)
text = models.TextField(max_length=400)
ordering = models.IntegerField(blank=True, null=True)
objects = RandomManager()
class PostPages(models.Model):
image_gallery = models.ManyToManyField(ShivaImage, blank=True,
related_name='gallery',)
# all the other fields...
objects = RandomManager()
的管理者设置use_for_related_fields
到True
将使其可在这一点上到在其上定义了这个经理为默认管理模型的所有关系。这是记录here
class MyManager(models.Manager):
use_for_related_fields = True
# ...
我想你只对你PostPages
模式启用,不是在你的Gallery
模型(或任何模型被称为是通过post_image_gallery
参考)。如果您想在此realtion manager上具有其他功能,则需要将use_for_related_fields = True
的自定义默认管理器添加到您的Gallery
模型中!
关于主题的完整性,Django的1.7(终于)支持using a custom reverse manager,所以你可以做这样的事情(从Django文档只是复制):
from django.db import models class Entry(models.Model): objects = models.Manager() # Default Manager entries = EntryManager() # Custom Manager b = Blog.objects.get(id=1) b.entry_set(manager='entries').all()
而且,在自定义管理,确保
class EventManager(models.Manager):
use_for_related_fields = True
def visible_events(self):
today = datetime.date.today()
# don't do this !!!
# unsuitable for related managers as could retrieve extraneous objects
# qs = super(EventManager, self).get_query_set()
# Use queryset proxy method as follows, instead:
qs = self.get_query_set()
qs = qs.filter(visible_from__lte=today, visible_to__gte=today)
return qs
class Event(models.Model):
visible_from = models.DateField(_(u'visible from'), null=False, blank=False)
visible_to = models.DateField(_(u'visible to'), null=False, blank=False)
concepts = models.ManyToManyField(Concept, through='ConceptEventRegistration')
objects = EventManager()
使用范例:
通过self.get_query_set访问查询集() 实现自定义过滤器时,代理方法从相关管理者被称为my_concept = Concept.objects.get(id=1)
# retrieve all events related to the object
my_concept.event_set.all()
# retrieve all visible events related to the object
my_concept.event_set.visible_events()
在Django 2.0 use_for_related_fields
是depricated https://docs.djangoproject.com/en/2.0/releases/1.10/#manager-use-for-related-fields-and-inheritance-changes
您应该使用base_manager_name
https://docs.djangoproject.com/en/2.0/ref/models/options/#django.db.models.Options.base_manager_name
这里有最新的文档https://docs.djangoproject.com/en/2.0/topics/db/managers/#using-managers-for-related-object-access
class MyModel(models.Model):
field1 = ...
field2 = ...
special_manager = MyManager()
class Meta:
base_manager_name = 'special_manager'
'base_manager_name'预计所讨论的管理器的名称是一个字符串,而不是实例。见[this](https://github.com/django/django/blob/8dc675d90f14a84ef95f16c7cc8100d9a04459b3/tests/custom_managers/models.py#L158)。 – Nobilis
@Nobilis谢谢,修正 –
我在两个模型中定义的经理。如果我理解的话,'objects'就是默认管理器。看到问题编辑,我在那里添加模型。 – I159
定义的_first_管理器成为默认管理器,无论它是否被称为“objects”或不... –
Uoo hooo!其作品!很可能有一些非常愚蠢的错误。因为现在没关系。 – I159