Группировка по и результат вложенности в Django Rest Framework

#python #sql #django #django-rest-framework #nested

Вопрос:

я работаю в API, и я хочу заказать по идентификатору DESC, но я также хочу группировать по client_id, чтобы я мог получить все вопросы от тех же клиентов, которые были заказаны, вложив результаты:

Это мой код:

models.py

 class QuestionsModel(models.Model):
    id = models.IntegerField()
    publication_id = models.IntegerField(blank=True, null=True)
    publication_title = models.CharField(max_length=255)
    publication_link = models.CharField(max_length=255)
    question = models.CharField(max_length=255)
    member_id = models.IntegerField()
    client_id = models.IntegerField()

   class Meta:
        managed = False
        db_table = 'questions'

 

serializers.py

 class QuestionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = QuestionsModel
        fields = '__all__'
 

views.py

 class QuestionsAPIView(generics.ListAPIView):
    def get_queryset(self):
        queryset = ''
        member_id = self.request.query_params.get('member_id')
        
        if member_id is not None and member_id.isnumeric():
            queryset = QuestionsModel.objects.filter(member_id=member_id).order_by('-id')
        return queryset
 

Результат:

     {
    "id": 848484,
    "publication_id": 4444,
    "publication_title": "Title publication",
    "publication_link": "Link",
    "question": "This is a test question",
    "member_id": 123456,
    "client_id": 500
    }
 

Что я хочу: группировать вопросы по client_id, поэтому желаемый выходной JSON может быть:

 {
"client_id": 500,
"question" : [
    "id": 848484,
    "publication_id": 4444,
    "publication_title": "Title publication",
    "publication_link": "Link",
    "question": "This is a test question",
    "member_id": 123456,
    "client_id": 500
 ],
[
    "id": 848485,
    "publication_id": 4445,
    "publication_title": "Title publication",
    "publication_link": "Link",
    "question": "This is a test question",
    "member_id": 123456,
    "client_id": 500
]
}
 

Примечания: Я использую SQL Server в качестве движка БД.

Ответ №1:

Если между клиентами и вопросами существует отношение «один ко многим», я бы посоветовал создать клиентскую модель и установить связь внешнего ключа между вопросами и их клиентом. Затем вы можете более легко использовать сериализаторы моделей DRF и вложенные отношения.

https://www.django-rest-framework.org/api-guide/relations/#nested-relationships

Вот упрощенная версия того, чего, я думаю, вы пытаетесь достичь:

models.py

 class Client(models.Model):
    id = models.IntegerField(primary_key=True)

class Question(models.Model):
    id = models.IntegerField(primary_key=True)
    question = models.CharField(max_length=255)
    client_id = models.ForeignKey(to=Client,on_delete=models.CASCADE,related_name='questions')
 

serializers.py

 class QuestionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Question
        fields = ['id','question']


class ClientSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True, read_only=True)

    class Meta:
        model = Client
        fields = ['id','questions']

 

views.py

 class ClientList(generics.ListAPIView):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer
 

Если я подключу это представление к URL-адресу и вызову GET для него, результирующая структура данных будет:

 [
    {
        "id": 1,
        "questions": [
            {
                "id": 1,
                "question": "questions 1"
            },
            {
                "id": 2,
                "question": "questions2"
            },
            {
                "id": 3,
                "question": "questions3"
            }
        ]
    }
]
 

Я не уверен, кто вы собираетесь использовать свой API, но как человек, который много работает с REST, эта структура данных для меня более интуитивно понятна, чем предложенная вами. Это список объектов клиента (хотя в этом примере он содержит только один) с вложенным списком объектов вопроса ниже. Расширяйте свои модели и уточняйте свой набор запросов по своему усмотрению!