48

カスタムマネージャーがいます。関連するオブジェクトに使いたいです。ドキュメントで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()

私はそれを1つのモデルに使用しました:

>>> 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()
4

4 に答える 4

28

マネージャを に設定use_for_related_fieldsすると、このマネージャをデフォルト マネージャとして定義したモデルTrue指すすべてのリレーションで使用できるようになります。これはここに文書化されています

class MyManager(models.Manager):
    use_for_related_fields = True
    # ...

PostPagesモデルではなく、モデルでのみ有効にしていると思いますGallery(または、 を介して参照されるモデルの名前は何でもpost_image_gallery)。このリアルション マネージャーに追加機能を持たせたい場合はuse_for_related_fields = TrueGalleryモデルにカスタムのデフォルト マネージャーを追加する必要があります。

于 2011-09-20T19:40:58.350 に答える
1

また、カスタム マネージャーでは、関連するマネージャーから呼び出されるカスタム フィルターを実装するときに、self.get_query_set() プロキシ メソッドを介してクエリセットにアクセスするようにしてください。

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()

使用例:

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()
于 2015-01-18T07:01:30.897 に答える