首页 文章

Django ORM通过多个模型访问用户表

提问于
浏览
7

views.py

我正在创建一个我想序列化并作为JSON返回的查询集 . 查询集如下所示:

all_objects = Program.objects.all()
test_data = serializers.serialize("json", all_objects, use_natural_keys=True)

除了“用户”模型(跨两个模型链接)之外,这将拉回所有内容 .

models.py

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

class Time(models.Model):
    user = models.ForeignKey(User)
    ...

class CostCode(models.Model):
    program_name = models.TextField()        
    ...

class Program(models.Model):
    time = models.ForeignKey(Time)
    program_select = models.ForeignKey(CostCode)
    ...

Question

我返回的数据有Time,Program和CostCode信息,但我无法查询'User'表 . 如何在同一个查询集中找回“用户名”(来自用户表)?

注意:我已将我的查询集更改为 all_objects = Time.objects.all() ,这会获取用户信息,但它不会't pull in ' CostCode' . 我的模型也有ModelManagers返回 get_by_natural_key 所以相关字段出现在我的JSON中 .

最终,我希望所有四个模型的数据都出现在我的序列化JSON字段中,我只是缺少'用户名' .

这是一张JSON对象当前如何出现在Firebug中的图片:
Firefox's Firebug showing the JSON object

谢谢你的帮助!

2 回答

  • 2

    乍一看似乎有点重量级,但你可以看看使用Django REST框架:
    http://www.django-rest-framework.org/api-guide/serializers#modelserializer

    您可以定义和使用序列化程序类,而无需对框架执行任何其他操作 . 序列化程序返回一个python dict,然后可以很容易地转储到JSON .

    要将每个相关模型的所有字段作为嵌套dicts,您可以执行以下操作:

    class ProgramSerializer(serializers.ModelSerializer):
        class Meta:
            model = Program
            depth = 2
    
    all_objects = Program.objects.all()
    serializer = ProgramSerializer(all_objects, many=True)
    json_str = json.dumps(serializer.data)
    

    要自定义每个模型包含哪些字段,您需要为每个模型定义ModelSerializer类,例如,仅为 time.user 输出 username

    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ('username', )
    
    class TimeSerializer(serializers.ModelSerializer):
        """
        specifying the field here rather than relying on `depth` to automatically
        render nested relations allows us to specify a custom serializer class
        """
        user = UserSerializer()
    
        class Meta:
            model = Time
    
    class ProgramSerializer(serializers.ModelSerializer):
        time = TimeSerializer()
    
        class Meta:
            model = Program
            depth = 1  # render nested CostCode with default output
    
    all_objects = Program.objects.all()
    serializer = ProgramSerializer(all_objects, many=True)
    json_str = json.dumps(serializer.data)
    
  • 3

    你真正想要的是Django本身不支持的"deep"对象序列化 . 这是一个常见问题,这里将详细讨论:Serializing Foreign Key objects in Django . 一些替代品可以看到这个问题 .

    通常Django希望您分别序列化Time,CostCode,Program和User对象(即每个对象的单独JSON数组)并通过ID引用它们 . ID可以是数字主键(PK),也可以是使用 natural_key 定义的"natural"键 .

    您可以使用 natural_key 返回所需的任何字段,包括user.username . 或者,您可以根据需要定义自定义序列化程序输出 . 这些方法中的任何一种都可能使得无法将数据加载回Django数据库,这对您来说可能不是问题 .

相关问题