#django-rest-framework
#django-rest-framework
Вопрос:
class budgetSerializer(serializers.ModelSerializer):
budget_used = serializers.SerializerMethodField()
budget_remain = serializers.SerializerMethodField()
total_budget = serializers.IntegerField(default=250000)
def get_budget_used (self,obj):
budget_used=budget.objects.filter(user=obj.user).aggregate(Sum('budget_stord__bytes'))
data = []
for val in budget_used.items():
if val.value > total_budget :
raise serializers.ValidationError('you exceed the total budget limit')
return f'budget : {(budget_used/1000)} '
def get_total_budget(self,obj):
total_budget = 250000
return f'total_budget: {(total_budget/1000)} '
def get_remain(self,obj):
remain = (total_budget) - (budget_used)
return remain
class Meta:
model = budget_u
fields = ("budget_used","total_budget","budget_remain")
MODEl
class budget_u(CreatedModel, UUIDPKModel):
budget_stord = models.ForeignKey('bud.Store', on_delete=models.SET_NULL, null=True, blank=True)
user = models.ForeignKey('user.user', on_delete=models.SET_NULL, null=False, blank=False)
Мне нужен вывод, подобный
{
" budget_used": "100",
"remain": "150G",
"total_budget": "250"
}
получение
Ошибка атрибута: объект ‘tuple’ не имеет атрибута ‘value’
Комментарии:
1.
budget_used.items()
возвращает повторяющийся кортеж из двух
Ответ №1:
Вы не обращаетесь к значению с помощью .value
, .items()
возвращает итерацию из 2-х кортежей, поэтому вы можете использовать итеративную распаковку в for
цикле. Но здесь вы можете просто использовать подписку для доступа к значению:
def get_budget_used(self, obj):
budget_used = budget_u.objects.filter(
user=obj.user
).aggregate(total=Sum('budget_stord__bytes'))['total'] or 0
if budget_used > 250000:
return 'you exceed the total budget limit'
return f'budget : {(budget_used/1000)}'
При этом довольно странно каждый раз возвращать строки. Часто сериализаторы возвращают числовые данные, поскольку их проще обрабатывать, например, с помощью скрипта JavaScript на стороне браузера или интеграции клиента.
Комментарии:
1. Спасибо, Виллем Ван Онсем, когда я использовал ваш код, я получаю эту ошибку TypeError: ‘>’ не поддерживается между экземплярами ‘NoneType’ и ‘int’
2. Ошибка типа: ‘>’ не поддерживается между экземплярами ‘NoneType’ и ‘int’
3. @user1007061: я полагаю, это потому, что нет связанного
budget_u
объекта? В этом случае вы можете использоватьor 0
.4. привет, в приведенном выше коде, когда я запускаю код, который я получаю для своего remain. def get_remain(self, obj): remain = (self.context.get(total_budget)) — (self.context.get(budget_used)) возвращает ошибку remain remain = (self.context.get(total_budget)) — (self.context.get(budget_used)) Ошибка типа: неподдерживаемые типы операндов для -: ‘NoneType’ и ‘NoneType’
5.Но
self.context
не имеет ниtotal_budget
, ниbudget_used
.context
содержит только объекты, которые вы сами передаете сериализатору. Даже если бы у него было это, это не сработало бы, поскольку ваши методы возвращают stringы, а не числа, следовательно, вычитание невозможно. Это одна из (многих) причин, по которой использование строк в качестве ответа не является хорошей идеей.