Как скрыть поле, являющееся правящим ключом, в сериализаторе на основе утверждения
Это мой сериализатор
class SparkleTemplateSerializer(serializers.ModelSerializer):
notifications = NotificationTemplateSerializer(source='notificationtemplate_set', many=True)
rules = RuleTemplateSerializer(source='ruletemplate_set', many=True)
class Meta:
model = SparkleTemplate
fields = ['id', 'name', 'description', 'enabled', 'run_schedule', 'notifications', 'rules']
Мне нужно показывать и скрывать поле "notifications", которое является внешним ключом, как вы можете видеть, но это должно происходить, если некоторая переменная является true или false.
Вот как я пытался сделать это, добавив приведенный ниже код в сериализатор, но я думаю, что это не работает из-за свойства fields в Meta
def to_representation(self, obj):
show = NotificationTemplate._meta.get_field('show')
rep = super(SparkleTemplateSerializer, self).to_representation(obj)
if show is False:
rep.pop('notifications', None)
return rep
Я также пробовал исключить "notifications" и создать другой сериализатор, но это не работает, так как "notifications" должен быть там, поэтому я получал ошибки. Спасибо
Мы можем удалить элементы в полученном словаре из to_representation()
, обратившись к атрибуту show
каждого элемента в notifications
.
В зависимости от того, как вы хотите, чтобы отображались уведомления, вот 2 варианта:
- Вариант-1: Если вы хотите удалить все
notifications
, если хотя бы 1show
являетсяFalse
.
- Вариант-2: Если вы хотите удалить только
notifications
, гдеshow
являетсяFalse
def to_representation(self, obj):
rep = super().to_representation(obj)
# Option 1: If you want to remove all notifications if at least 1 show is False
# if any(notif["show"] is False for notif in rep["notifications"]):
# del rep['notifications'] # Or rep.pop('notifications')
# Option 2: If you only want to remove the notifications where show is False
rep["notifications"] = list(filter(lambda notif: notif["show"], rep["notifications"]))
return rep
Вы можете использовать prefetch_related
метод с Prefetch
объектом , обычно это используется для решения N + 1 проблемы, но другая вещь позволяет предоставить queryset для префетчированного объекта.
Следовательно, вы можете изменить свой вид следующим образом:
from django.db.models import Prefetch
class SparkleTemplateView(ListAPIView):
serializer_class = SparkleTemplateSerializer
def get_queryset(self):
user = self.request.user
shown_notifications = NotificationTemplate.objects.filter(show=True)
queryset = SparkleTemplate.objects.filter(
branch_owner=user.branch
).prefetch_related(
Prefetch('notificationtemplate_set', queryset=shown_notifications)
)
return queryset
Теперь вы можете не модифицировать сериализаторы to_representation
, поскольку вы уже отфильтровали их, чтобы показывать только необходимые NotificationTemplate
объекты.