Заполнение json из нескольких django моделей - PullRequest
0 голосов
/ 24 января 2020

У меня есть следующие 2 Django модели, Lessons и UserLessons.

Lessons будут созданы администратором, а UserLessons в основном, когда пользователь выполняет Lesson или completed Lesson, связанные внешним ключом. UserLesson не обязательно содержит запись Lesson, пока пользователь фактически не начнет с этой указанной c единицы.

Поскольку я создаю API (с DRF), мне нужно перечислить Полный список всех уроков - легко. LessonList = Lesson.objects.all().values('id', 'title')

Это возвращает

[
    {
        "id": 1,
        "title": "Lesson 1"
    },
    {
        "id": 2,
        "title": "Lesson 2"
    },
    {
        "id": 3,
        "title": "Lesson 3"
    }
]

Однако мне нужно иметь возможность объединить его с UserLesson (например, UserLessonList = UserLesson.objects.filter(user=request.user).values('id', 'lesson__id', 'completed'), который в настоящее время возвращает

[
    {
        "id": 2,
        "lesson__id": 1,
        "completed": true
    },
    {
        "id": 3,
        "lesson__id": 2,
        "completed": true
    }
]

В идеале , он должен вернуть все уроки из БД и завершенные значения, по умолчанию completed: false, если этот конкретный c урок не существует в БД.

Есть предложения?

Редактировать:

Просмотры

class LessonList(APIView):

    permission_classes = (IsAuthenticated,)

    def get(self, request):

        LessonList = Lesson.objects.all().values('id', 'title')
        UserLessonList = UserLesson.objects.filter(user=request.user).values('id', 'lesson__id', 'completed')





        return Response(LessonList)

Модели

class Lesson(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    title = models.CharField(max_length=250, verbose_name=u'Title')
    slug = models.SlugField(null=True, blank=True, help_text='eg, lesson-1-whats-up')
    published = models.BooleanField(default=False)

    def __str__(self):
        return(self.title)

class UserLesson(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, null=True)
    completed = models.BooleanField(default=False)

    def __str__(self):
        text = str(self.lesson.title)
        return(text)

1 Ответ

1 голос
/ 24 января 2020

Вы должны использовать ModelViewSet и сериализаторы. Точно ModelSerializer . Как то так:

class LessonSerializer(serializers.ModelSerializer):
    completed = serializers.SerializerMethodField()
    class Meta:
        model = Lesson
        fields = ['id', 'title', 'completed']

   def get_completed(self, obj):
        user = self.context.get('request').user
        return UserLesson.objects.filter(user=user, lesson=obj, completed=True).exists()

class LessonViewSet(viewsets.ModelViewSet):
    queryset = Lesson.objects.filter(published=True)
    serializer_class = LessonSerializer
    permission_classes = [IsAuthenticated]

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