У меня возникла проблема, когда я выбираю отдельное значение из БД.
Вот моя модель:
class Shift(models.Model):
shiftid = models.CharField(max_length=15)
shiftdesc = models.CharField(blank = False, null= False, max_length=20)
dayname = models.CharField(blank = False, null= False, max_length=20)
class Meta:
unique_together = ('shiftid','dayname')
Это результирующая структура данных:
shiftid shiftdesc dayname
shift1 desc1 1
shift1 desc2 1
shift1 desc1 1
Я хочу, чтобы это было так:
shiftid shiftdesc dayname
shift1 desc1 1
shift1 desc2 1
Я пытаюсь выбрать записи следующим образом:
@action(methods=['get'], detail=False)
def shiftsum(self, request):
newest = self.get_queryset().order_by('shiftid','dayname').values('shiftid','dayname').distinct()
serializer = self.get_serializer_class()(newest)
return Response(serializer.data)
Когда я пытаюсь так, я всегда получаю эту ошибку:
QuerySet object has no attribute 'shiftid'
Кроме того, я хотел бы знать, как выбрать отличное значение? Я новичок в Django и ценю любую помощь.






По умолчанию сериализаторы не обрабатывают списки объектов. Вам нужно передать many=True, чтобы он обработал каждый элемент и вывел список (остальные документы фреймворка).
self.get_serializer_class()(newest, many=True)
Это даст вам список дней, как вы ожидаете:
[
{ "shiftid": "shift1", "dayname": "1" }
]
Ваш отчет в порядке. Пример отдельного запроса будет выглядеть так же, как ваш:
User.objects.values('field').order_by('field').distinct()
Проблема с вашим окончательным запросом заключается в том, что вы выбираете только 2 из 3 нужных полей, за исключением shiftdesc.
На самом деле нет логического способа получить это значение, поскольку по определению вы начинаете с N и заканчиваете 1.
Если вам просто нужно значение ЛЮБЫЕ для него, скажем, для отладки или отображения, вы можете использовать .annotate() следующим образом:
query = (
Shift.objects.values('shiftid', 'dayname')
.annotate(shiftdesc=Max('shiftdesc'))
.annotate(ct=Count('*')) # get count of rows in group
.order_by('shiftid', 'dayname')
.distinct()
)
Посмотрите на аннотации/агрегации, можно сделать более сложные вещи, которые могут помочь, и некоторые вещи, специфичные для базы данных, которые могут быть действительно полезными.
Вот полный пример с использованием пользовательской таблицы django по умолчанию. Вы не предоставили достаточно информации для дальнейшей отладки.
import json
from rest_framework.serializers import *
User.objects.create(email='x1@e', first_name='Angela', last_name='Smith')
User.objects.create(email='x2@e', first_name='James', last_name='Smith')
User.objects.create(email='x3@e', first_name='James', last_name='Joyce')
query = User.objects.values('last_name') \
.order_by('last_name') \
.annotate(first_name=Max('first_name')) \
.annotate(ct=Count('email')).distinct()
class X(Serializer):
last_name = CharField()
first_name = CharField()
ct = IntegerField()
data = X(query, many=True).data
print(json.dumps(data, indent=4))
[
{
"last_name": "Joyce",
"first_name": "James",
"ct": 1
},
{
"last_name": "Smith",
"first_name": "James",
"ct": 2
}
]
Я могу легко запустить этот код напрямую в консоли. Вам придется сказать мне больше, чем «у меня ошибка». Мои навыки психической отладки немного заржавели.
если я вернусь как «return Response (query)», я получу результат, но если я сериализую и отвечу, как «serializer = self.get_serializer_class () (query) return Response (serializer.data)», произойдет ошибка.
О, пожалуйста, еще один вопрос: если у меня всего 5 полей, но мне нужны только эти 3 поля, как выбрать только эти 3 поля? Мне нужно создать новый сериализатор?
@Jze Этот ответ уже касается исходного вопроса. Пожалуйста, попробуйте ограничить количество вопросов до 1 на сообщение и создать новый вопрос, как только вы решите эту проблему.
Пожалуйста, помогите мне проверить мой новый вопрос => stackoverflow.com/questions/57179287/…
Я меняю, как вы сказали, но все еще получаю ошибку. Я понятия не имею, почему.