Django模型序列化返回自然主键值示例代码

  


  

  

在设计表结构时,难免需要建立一些外键关联,例如这样两个模型:
  

        django。数据库导入模型      类人(models.Model):   用户名=models.CharField (max_length=100)   生日=models.DateField ()      类的书(models.Model):   name=models.CharField (max_length=100)   作者=models.ForeignKey(人,>   django。核心进口序列化器   book_json=序列化器。序列化(json, Book.objects.get (pk=1)      

JSON序列化结果如下:
  

        {   “pk”: 1、   “模型”:“store.book”,   “字段”:{   “名称”:“主要是无害的”,   “作者”:42   }   }      

这个“作者”:42对用户来说相当于未知,我们需要的是人表中主键为42的用户姓名,即用户名的值。
  

  


  

  

在Django官方文档的“序列化”一节中提到了用模型。经理处理的方案,在搜索解决方案过程中,也接触到Django-REST-Framework肾盂输尿管)了解到DRF中的序列化器模块也能解决这类问题。那我们不妨对比一下两种解决方案。
  

  

<强>方案一:模型。经理
  

  

根据文档,要返回自然主键,我们需要定义一个模型管理器,创建一个get_by_natural_key方法,如下:
  django。

db导入模型         django。数据库导入模型      类PersonManager (models.Manager):   def get_by_natural_key(自我、用户名):   返回self.get(用户名=用户名)      类人(models.Model):   用户名=models.CharField (max_length=100)   生日=models.DateField ()   对象=PersonManager ()      

然后再次序列化书实例:
  

        django。核心进口序列化器   book_json=序列化器。序列化(json, Book.objects.get (pk=1), use_natural_foreign_keys=True)      

得到新的结果如下:
  

  
  

{
  ,,“pk”: 1,
  ,,“模型”:“商店。书”,
  ,,“字段”:{
  ,,,,,,“名称”:“主要是无害的”,
  ,,,,,,“作者”(“DouglasAdams”):
  ,,}
  }
  

     

如果需要对其他应用的数据模型做修改,例如使用了django.auth.User(默认认证后端)作为Book 用户的外键,要想不修改模型又使用新的模型管理器,可以使用代理模式完成:
  

        django。数据库导入模型      类新任(models.Manager):   #……   通过      类MyPerson(人):   对象=新任()      类元:   代理=True      

总的来说,这个方案可以完美解决我所遇到的问题,代码量稍微大一些,但是也更灵活。
  

  

<强>方案二:DRF的序列化器
  

  

下面我们试试用Django-REST-Framework的序列化模块:
  

        从rest_framework进口序列化器   从进口得书      类BookSerializer (serializers.ModelSerializer):   author_name=serializers.CharField(源=癮uthor.username”)      类元:   模型=书   字段=' __all__ '      

这段代码表示,在序列化书实例时,添加一个新的属性author_name,该值的来源为源参数定义的外键作者实例的自然主键用户名。
  

  

然后是执行序列化的过程:
  

        queryset=Book.objects.get (pk=1)   BookSerializer(实例=queryset)      

序列化结果:
  

  
  

{
  ,,“id”: 1、
  ,,“名称”:“主要是无害的”,
  ,,“作者”:42岁,
  ,,:“author_name DouglasAdams”
  }
  

     

当然,序列化一批书实例也是可以的:
  

        queryset=Book.objects.all ()   BookSerializer (=queryset实例,许多=True)      

序列化结果:
  

  
  

(
  ,,{
  ,,,,,,“id”: 1、
  ,,,,,,“名称”:“主要是无害的”,
  ,,,,,,“作者”:42岁,
  ,,,,,,:“author_name DouglasAdams”
  ,,},
  ,,{
  ,,,,,,“id”: 2,
  ,,,,,,“名称”:“哈利波特”,

Django模型序列化返回自然主键值示例代码