2015-12-17 5 views
1

Я использую Django Managers, чтобы сделать более высокий API для взаимодействия с моей базой данных и сохранения моего кода более чистым и читаемым. Но в случае, если у меня есть отношения Foreignkey, я не могу использовать менеджера модели ForeignKey. Запросы являются более сложными, как показано ниже, но я упростил пример так, он может быть проще читать и получить представление о том, на вопрос:Как получить доступ к пользовательским методам QuerySet из Менеджера ForeignKey

models.py:

class Community(models.Model): 
    objects = CommunityManager() 
    ... 


class Inscription(models.Model): 
    objects = InscriptionManager() 

    ... 
    community = models.ForeignKey("Community", related_name="inscriptions") 
    created_at = models.DateTimeField() 

managers.py:

from datetime import date 
from django.db import models 


class InscriptionQuerySet(models.query.QuerySet): 
    def by_day(self, day=date.today()): 
     return self.filter(created_at__day=day) 

    ... # more queries 


class InscriptionManager(models.Manager): 
    def get_query_set(self): 
     return InscriptionQuerySet(self.model, using=self._db) 

    def today(self): 
     return self.get_query_set().by_day() 

    ... # more queries 


class CommunityQuerySet(models.query.QuerySet): 
    def by_type(self, type): 
     return self.filter(type=type) 

    ... # more queries 


class CommunityManager(models.Manager): 
    def get_query_set(self): 
     return OrganistaionQuerySet(self.model, using=self._db) 

    def by_type(self, type): 
     return self.get_query_set().by_type(type) 

    ... # more queries 

Использование:

Inscription.objects.by_day() # return correctly all the inscriptions made today 
Community.objects.by_type('type1') # return correctly all Communities that match 

Проблема: но здесь кроется проблема

community_b = Community.objects.get(id=12) 
community_b.inscriptions.by_day() 
>>> AttributeError: 'ForeignRelatedObjectsDescriptor' object has no attribute 'by_day' 

Как фиксируем это. Как настроить менеджера, чтобы принять во внимание отношение моделей.

+2

Можете ли вы попробовать добавить 'use_for_related_fields = True' в свой' InscriptionManager'? Проверьте это: https://docs.djangoproject.com/en/1.9/topics/db/managers/#controlling-automatic-manager-types –

+0

Почему у вас есть 'QuerySet' и' Manager' для обеих моделей? –

+0

@RohitJain Я пробовал это, но по-прежнему ту же ошибку. Да, он будет оптимизирован для одного менеджера, но теперь для простоты я использую ясли для каждой модели. – DhiaTN

ответ

1

Я не вижу необходимости как Manager, так и QuerySet в вашем подходе. Вы могли бы просто покончить с QuerySet. Это, как я обычно реализую собственные менеджер, и я попытался доступом метода пользовательского менеджера по обратной связи в одном из моих проектов, и она отлично работает:

class InscriptionQuerySet(models.QuerySet): 
    def by_day(self, day=date.today()): 
     return self.filter(created_at__day=day) 

    def today(self): 
     return self.by_day() 

class CommunityQuerySet(models.QuerySet): 
    def by_type(self, type): 
     return self.filter(type=type) 

, а затем в вашей модели, изменить ваш objects как это:

class Community(models.Model): 
    objects = CommunityQuerySet.as_manager() 
    ... 


class Inscription(models.Model): 
    objects = InscriptionQuerySet.as_manager() 

Я думаю, что с этой настройкой вы сможете получить доступ к настраиваемому запросу.

+0

Это работает очень для меня. Подход, который я использую, предлагается здесь [django documentation] (https://docs.djangoproject.com/en/1.9/themes/db/managers/# call-custom-queryset-methods-from-the-manager), и я не знаю, в чем разница между этими двумя подходами. Но спасибо за подсказку. – DhiaTN

Смежные вопросы