Как отобразить данные из двух моделей без создания новой модели в Django? - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть две модели с одним общим полем (электронная почта). Я использую viewset.ModelViewset для составления списка и создания данных в обеих моделях.

My models.py:

class Schema(models.Model):
    """Database model for Schema """

    name= models.TextField()
    version = models.TextField()
    email = models.EmailField(unique = True )


    def __str__(self):
        return self.email

class Status(models.Model):
    """ Model For status """
    email = models.EmailField(unique = True )
    status = models.TextField()

    def __str__(self):
        return self.email

my view.py:

class StatusViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):

    queryset = models.Status.objects.all()
    serializer_class = serializers.StatusSerializer


class SchemaViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):

    queryset = models.Schema.objects.all()
    serializer_class = serializers.SchemaSerializer

I хочу переопределить функцию List в Status Viewset, чтобы отобразить все детали этого пользователя. Для примера: из набора настроек схемы я создал:

{
    "id": 1,
    "name": "Yatharth",
    "version": "1.1",
    "email": "yatharth@test.com"
}

и из набора просмотра Staus у меня POST статус электронной почты: yatharth@test.com для Активный. Из GET Status VIewset я хочу отобразить данные, как это:

{
    "name": "Yatharth",
    "version": "1.1",
    "email": "yatharth@test.com"
    "status": "Active"

}

Как это сделать? Я нашел select_related и prefetch_related в Django ORM, но не знаю, как их использовать

1 Ответ

2 голосов
/ 24 апреля 2020

Из вашей базы данных я не нахожу причин для создания отдельной таблицы для Status. Если вам все еще нужно создать отдельную таблицу, вы должны управлять отношениями между ними, используя ForeignKey или OneToOneField. Это сделает вашу задачу намного проще. Для вашей текущей структуры вы должны будете написать свой сериализатор следующим образом:

class SchemaSerializer(serializer.ModelSerializer):
    status = serializer.SerializerMethodField()

    def get_status(self, instance):
        status = Status.objects.filter(email=instance.email)
        if status.exists():
            return status.first().status

    class Mete:
        model = Schema
        fields = ('name', 'version', 'email', 'status')

Проще говоря, создайте SerializerMethodField и определите его логику c получения данных на основе объекта Schema .

Если вы измените свою модель

class Schema(models.Model):
    """Database model for Schema """

    name= models.TextField()
    version = models.TextField()
    email = models.EmailField(unique = True )


    def __str__(self):
        return self.email

class Status(models.Model):
    """ Model For status """
    schema = models. OneToOneField(to=Schema, related_name='schema_status')
    status = models.TextField()

    def __str__(self):
        return self.email

Эта структура поможет вам получить доступ к соответствующему Status объекту Schema, например schema_obj.schema_status, где schema_status равно related_name. Вы должны помнить, что это будет работать только тогда, когда у вас есть объект Status против объекта Schema. Поэтому я поставил if hasattr(instance, 'schema_status') нижеприведенный метод serialzer get_status.

Serializer

class SchemaSerializer(serializer.ModelSerializer):
    status = serializer.SerializerMethodField()

    def get_status(self, instance):
        if hasattr(instance, 'schema_status'):
            return instance.schema_status.status

    class Mete:
        model = Schema
        fields = ('name', 'version', 'email', 'status')
...