How to use custom manager with related objects?

前端 未结 4 1604
无人共我
无人共我 2020-12-02 20:08

I have a custom manager. I want to use it for related objects. I found use_for_related_fields in docs. But it does not work the way I used it:

class Random         


        
相关标签:
4条回答
  • 2020-12-02 20:28

    Also, in the custom manager, make sure to access the queryset via the self.get_query_set() proxy method when implementing custom filters to be called from related manager:

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

    Sample usage:

    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()
    
    0 讨论(0)
  • 2020-12-02 20:31

    For completeness of the topic, Django 1.7 (finally) supports using a custom reverse manager, so you can do something like that (just copying from the django docs):

    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()
    
    0 讨论(0)
  • 2020-12-02 20:37

    Setting use_for_related_fields to True on the manager will make it available on all relations that point to the model on which you defined this manager as the default manager. This is documented here

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

    I suppose you have it only enabled on your PostPages model, not on your Gallery model (or whatever the model is called that is referenced through post_image_gallery). If you want to have additionally functionality on this realtion manager you need to add a custom default manager with use_for_related_fields = True to your Gallery model!

    0 讨论(0)
  • 2020-12-02 20:39

    In django 2.0 use_for_related_fields is deprecated https://docs.djangoproject.com/en/2.0/releases/1.10/#manager-use-for-related-fields-and-inheritance-changes

    You should use base_manager_name: https://docs.djangoproject.com/en/2.0/ref/models/options/#django.db.models.Options.base_manager_name

    Updated docs: 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'
    
    0 讨论(0)
提交回复
热议问题