Параметризованная недвижимость в Джанго - PullRequest
3 голосов
/ 22 сентября 2019

Например, у меня есть две модели:

class Page(models.Model):
   # Some fields
   ...

   @property
   def title(self):
      return PageTranslation.objects.get(page=self, language=language).title # I can not pass property to the parameter

class PageTranslation(models.Model):
   page = models.ForeignKey(Page)
   title = models.CharField()

И некоторое представление DRF, метод get_queryset которого выглядит следующим образом:

def get_queryset(self):
   return Page.objects.all()

И сериализатор:

class PageSerializer(serializers.ModelSerializer):
   class Meta:
       model = Page
       fields = (..., 'title',) # title = property

Я хочу вернуть QuerySet с экземплярами модели страницы и использовать свойство title в сериализаторе, но не могу передать язык (который задан где-то в запросе - заголовки, параметр запроса и т. Д.).

Как правильно это сделать?

Ответы [ 2 ]

1 голос
/ 23 сентября 2019
from django.utils.translation import get_language
from django.config import settings



class Page(models.Model):

    @property
    def title(self):
        language = get_language() or settings.LANGUAGE_CODE
        return PageTranslation.objects.get(page=self, language=language).title

get_language() дает вам текущий активный язык, если i18n отключен, он дает вам None, и для этого у нас есть запасной вариант settings.LANGUAGE_CODE.

Для части сериализатора IЯ думаю, что вы должны явно сказать, что ваше свойство является полем, ModelSerializer находит только фактические поля базы данных для вас, ничего больше.

class PageSerializer(serializers.ModelSerializer):
    title = serializers.Field()

    class Meta:
        model = Page
        fields = (..., 'title',)
0 голосов
/ 23 сентября 2019

Регистрация django.middleware.locale.LocaleMiddleware в настройках вашего проекта .Это делает свойство LANGUAGE_CODE доступным в request

В представлении DRF, где есть контекст request, отфильтруйте QuerySet по языку.

def get_queryset(self):
   return Page.objects.filter(language=self.request.LANGUAGE_CODE)

Затем вычислите titleсвойство, объявленное в модели Page, не является необходимым и неэффективным.

Вот почему:

N запросов выполняется для каждой записи в исходном QuerySet, чтобы сериализовать значение для поля заголовка.Существует большая вероятность возникновения проблемы N + 1, когда другая модель имеет отношение «многие ко многим» с Page.

Кроме того, сериализованные результаты могут быть несовместимыми, поскольку значение title может быть null в тех случаях, когда запись для языка не существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...