【问题标题】:using Django Rest framework to serialize custom data types and return response使用 Django Rest 框架序列化自定义数据类型并返回响应
【发布时间】:2015-04-03 13:11:30
【问题描述】:

大多数关于 Django Rest Framework 的教程都解释了使用 Django 模型和进行 CRUD 操作。如果我使用 JSON 序列化程序,那么用户模型上的 GET 请求会以 JSON 格式返回用户对象的属性。

我正在设计我的 Django 应用程序来处理查询并返回响应。 例如,我提供了一个 REST API 来获取以下查询的结果

"获取用户名和薪水超过XXX的部门"

这是我的 Django 模型:

class UserProfile(AbstractUser):
    age = models.PositiveIntegerField(_("age"))
    salary=models.PositiveIntegerField(_("salary"))

AUTH_USER_MODEL = "profiles.UserProfile"
User = get_user_model()

class Department(models.Model):
      users=models.ForeignKey(User)
      dept_name = models.CharField(max_length=30)

现在我有以下 DTO(数据传输对象):

class CustomResponse(object):

def __init__(self, user_name, salary, dept_name):
      self.user_name = user_name
      self.salary = salary
      self.dept_name=dept_name

在我使用 DRF 实现的 REST 服务中,我想要以下内容

@api_view(['GET'])
def getNameandDept(salary):
    users=User.objects.filter(salary__gt=salary)
    toreturn=[]
    for user in users:
        response=CustomResponse(user.first_name,user.salary,user.dept_name)
        to_return.append(response)
    return Response(to_return)

我不确定使用 Django rest 框架提供的工具来实现上述内容的正确方法是什么。

我期待这样的回应

[{user_name:"matt", salary:"5000", dept_name:"ENG"},{user_name:"smith",salary:"4000", dept_name:"HR"}....]

谢谢

编辑

我希望 DRF 为这种序列化提供开箱即用的工具。我一直在使用执行此序列化的 JAX-RS API(jersey 和 RESTeasy)。

【问题讨论】:

    标签: python json django django-rest-framework


    【解决方案1】:

    您实际上并不需要 REST 框架。您只需要定义一个serializer 类,而不是您拥有的CustomResponse

    serializers.py

    from django.core.serializers.json import Serializer
    
    class UserSerializer(Serializer):
        def get_dump_object(self, obj):
            mapped_object = {
                'user_name': obj.first_name,
                'salary': obj.salary,
                'dept_name': obj.dept_name
            }
    
            return mapped_object
    

    然后在你的views.py

    from myapp.serializers import UserSerializer
    
    def getNameandDept(request, salary):
        users = User.objects.filter(salary__gt=salary)
        serializer = UserSerializer()
        return HttpResponse(serializer.serialize(users), mimetype='application/json')
    

    不要忘记在 urls.py 中定义 salary 参数

    url(r'^users/(?P<salary>\d+)$', views.getNameandDept, name='getNameandDept'),
    

    PS。您绝对也可以使用 DRF 做到这一点。这是一个基本的GET 调用(按薪水过滤对序列化程序没有影响),所以你需要做的就是定义一个只有三个字段的ModelSerializer 子类

    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ('first_name', 'salary', 'dept_name')
    

    然后序列化输出(注意语法略有不同)

    serializer = UserSerializer(users)
    return Response(serializer.data)
    

    【讨论】:

    • 当你提到在 DRF 中使用 ModelSerializer 时,你是在序列化整个用户对象。它序列化所有模型的属性。但我只对这个特定 GET 请求的用户的某些属性感兴趣。例如:薪水、名字、部门。不是其他属性。
    • 你可以在ModelSerializer中指定你想要的字段,如果需要也可以重命名,见django-rest-framework.org/api-guide/serializers/…
    • 附言。这种对 DRF 的利用与使用 Django 内部序列化程序一样开箱即用。语法略有不同,代码量是相同的。 (除了 DRF 有一些不错的请求类型等装饰器)
    • 是的,Django 内部和 DRF 序列化程序都希望处理模型对象,而不仅仅是序列化某物的所有属性。 tbh 我认为定义 DTO 与定义序列化程序之间没有太大区别。
    • 好吧,在后一种情况下,您将需要 DTO 和序列化程序。但我想说,我可以只使用 DTO 并且框架为我处理序列化(就像 JAX-RS 等 Java 框架一样)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 2021-12-21
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多