如何在Django模型中添加无需ForeignKey的对象字段
实现嵌套对象字段(无需外键关联)的方案
要实现你需要的pressure这类嵌套对象字段,核心是用Django的JSONField存储结构化数据,再通过DRF的序列化器将其处理成嵌套格式。下面分步骤给出可直接复用的代码示例:
1. 模型(Model)配置
用JSONField存储嵌套的pressure数据,它能直接保存字典结构,且支持后续的查询操作:
from django.db import models import uuid class Observation(models.Model): professional = models.UUIDField() # 匹配示例中的UUID格式字符串 observations = models.CharField(max_length=255) date = models.DateTimeField() # 初始化默认值,和你需要的结构一致 pressure = models.JSONField(default=lambda: {"systolic_pressure": 0, "diastolic_pressure": 0})
2. 序列化器(Serializer)配置
推荐用子序列化器的方式处理嵌套结构,既能保证数据格式验证,又能自动生成你要的JSON结构:
from rest_framework import serializers from .models import Observation # 定义子序列化器,专门处理pressure的字段验证和格式转换 class PressureSerializer(serializers.Serializer): systolic_pressure = serializers.IntegerField(min_value=0) diastolic_pressure = serializers.IntegerField(min_value=0) class ObservationSerializer(serializers.ModelSerializer): # 关联子序列化器,自动将JSON字典转为嵌套对象 pressure = PressureSerializer() class Meta: model = Observation fields = ['id', 'professional', 'observations', 'date', 'pressure'] def create(self, validated_data): # 直接用验证后的字典创建模型实例 return Observation.objects.create(**validated_data) def update(self, instance, validated_data): # 单独处理pressure字段的更新 instance.pressure = validated_data.get('pressure', instance.pressure) # 更新其他字段 for field in ['professional', 'observations', 'date']: setattr(instance, field, validated_data.get(field, getattr(instance, field))) instance.save() return instance
如果不需要严格的字段验证,也可以简化为DictField:
class ObservationSerializer(serializers.ModelSerializer): pressure = serializers.DictField(child=serializers.IntegerField()) class Meta: model = Observation fields = ['id', 'professional', 'observations', 'date', 'pressure']
3. 视图(View)配置
用DRF的ModelViewSet快速实现完整的增删改查(CRUD)操作:
from rest_framework import viewsets from .models import Observation from .serializers import ObservationSerializer class ObservationViewSet(viewsets.ModelViewSet): queryset = Observation.objects.all() serializer_class = ObservationSerializer
4. URL路由配置
注册视图集,生成对应的CRUD接口:
from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import ObservationViewSet router = DefaultRouter() router.register(r'observations', ObservationViewSet) urlpatterns = [ path('', include(router.urls)), ]
测试示例
发送POST请求到/observations/,请求体格式完全匹配你给出的示例:
{ "professional": "d83876a6-69eb-4946-a0f7-56fd39cbd6a8", "observations": "Update", "date": "2022-03-22T21:45:37Z", "pressure": { "systolic_pressure": 120, "diastolic_pressure": 80 } }
GET请求返回的响应也会保持pressure的嵌套对象格式。
内容的提问来源于stack exchange,提问作者atbusch
相关产品推荐
相关产品推荐

