首页 > 解决方案 > Django Serializer 将参数传递给模型函数

问题描述

Django 和 DRF 的新手,我在模型属性中有一个接受参数的方法。通过具有默认参数的序列化程序类并获得 JSON 响应,我设法将其称为成功。我的问题是我无法将参数传递给名为 balance 的函数。我已经成功地将我的论点从视图传递到序列化程序类,但从序列化程序到我失败的模型。我以为会不胜感激。

模型.py

class Item(models.Model):
   entered_by = models.ForeignKey(User, on_delete=models.PROTECT)
   name = models.CharField(max_length=50, blank=True)

   @property
   def balance(self, stock_type='Retail'):
      stock = Stock.objects.filter(item=self, type=stock_type, status='InStock').aggregate(models.Sum('quantity')).get('quantity__sum')
      return stock or 0

视图.py

def getItemInfo(request):
   if request.is_ajax and request.method == "GET":
      id = request.GET.get("item_id", None)
      sell_type = request.GET.get("sell_type", None)
      item = Item.objects.get(id=id)
      if item:
         serializer = ItemSerializer(item, context={'sell_type':sell_type})
         return JsonResponse(serializer.data, status = 200, safe=False)
      else:
         return JsonResponse({"data":False}, status = 400)

序列化程序.py

from rest_framework import serializers
from .models import Item

class ItemSerializer(serializers.ModelSerializer):
   balance = serializers.SerializerMethodField()

   class Meta:
      model = Item
      fields = ('entered_by', 'name', 'balance', 'sell_mode')
   
   def get_balance(self, object):
      sell_type = self.context.get("sell_type")
      if sell_type:
         return object.balance(sell_type)
      return object.balance

我得到 'int'对象的错误是不可调用的

标签: djangodjango-rest-framework

解决方案


无法调用@property。所以我在Item模型中创建了成员变量和setter(带计算)方法,然后确保setter方法将在get_balance序列化方法中被调用,就在返回余额之前。

Django ORM 模型本身只是一个类;您可以做任何类可以做的事情,而不仅仅是与 ORM 链接。

我的代码:

模型.py

from django.db import models
from django.contrib.auth.models import User

class Item(models.Model):
   entered_by = models.ForeignKey(User, on_delete=models.PROTECT)
   name = models.CharField(max_length=50, blank=True)

   _balance = 0

   def calculate_balance(self, stock_type='Retail'):
      stock = Stock.objects.filter(item=self, type=stock_type, status='InStock').aggregate(
          models.Sum('quantity')).get('quantity__sum')
      self._balance = stock or 0

   @property
   def balance(self):
      return self._balance

序列化程序.py

from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Item


class ItemSerializer(serializers.ModelSerializer):
   balance = serializers.SerializerMethodField()

   class Meta:
      model = Item
      fields = ('entered_by', 'name', 'balance')

   def get_balance(self, object):
      sell_type = self.context.get("sell_type")
      if sell_type:
          object.calculate_balance(sell_type)
      return object.balance

视图.py

from .models import Item
from .serializer import ItemSerializer
from django.http.response import JsonResponse

def getItemInfo(request):
    if request.is_ajax and request.method == "GET":
        id = request.GET.get("item_id", None)
        if id is None:
            return JsonResponse({"data": False}, status=400)
        sell_type = request.GET.get("sell_type", None)
        try:
            item = Item.objects.get(id=id)
            serializer = ItemSerializer(item, context={'sell_type': sell_type})
            return JsonResponse(serializer.data, status=200, safe=False)
        except Item.DoesNotExist:
            return JsonResponse({"data": False}, status=400)

推荐阅读