Django Rest Framework中用户与模型一对多关系构建及接口实现问题
周数关联多用户的Schema模型与接口实现解决方案
1. 修正模型关系
你当前使用的ForeignKey是错误的——ForeignKey表示多对一关系(多个Schema对应一个用户),但你的需求是一对多/多对多(一个Schema对应多个用户,一个用户也可属于多个周的Schema),因此需要替换为ManyToManyField:
from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator class Schema(models.Model): week = models.PositiveIntegerField( primary_key=True, validators=[MinValueValidator(1), MaxValueValidator(53)], ) # 多对多关联MyUser,related_name设为更清晰的名称,方便反向查询 users = models.ManyToManyField( MyUser, related_name="week_schemas", blank=True ) class Meta: ordering = ('week',)
2. 序列化器实现(支持“存在更新/不存在创建”逻辑)
重写序列化器的create方法,利用update_or_create直接实现需求,同时用PrimaryKeyRelatedField简化用户数据的接收:
from rest_framework import serializers from .models import Schema, MyUser class SchemaSerializer(serializers.ModelSerializer): # 接收用户ID数组,自动验证用户是否存在 users = serializers.PrimaryKeyRelatedField( many=True, queryset=MyUser.objects.all(), required=False ) class Meta: model = Schema fields = ('week', 'users') def create(self, validated_data): # 取出用户ID列表,默认空数组 user_ids = validated_data.pop('users', []) # 根据week查找或创建Schema实例 schema, _ = Schema.objects.update_or_create( week=validated_data['week'], defaults=validated_data ) # 清空原有用户,批量添加新用户 schema.users.clear() schema.users.add(*user_ids) return schema def update(self, instance, validated_data): user_ids = validated_data.pop('users', []) # 调用父类更新其他字段(此处week为主键不可修改) instance = super().update(instance, validated_data) # 替换用户列表 instance.users.clear() instance.users.add(*user_ids) return instance
3. 正确的Postman请求格式
无需传递完整用户对象,只需传入周数和用户ID数组即可:
{ "week": 32, "users": [1, 2] }
- 若要设置空用户列表,可传
"users": []或省略该字段(序列化器已设required=False)
4. 视图层配置建议
使用ModelViewSet并指定lookup_field为week(因为主键是周数而非默认的id):
from rest_framework import viewsets from .models import Schema from .serializers import SchemaSerializer class SchemaViewSet(viewsets.ModelViewSet): queryset = Schema.objects.all() serializer_class = SchemaSerializer lookup_field = 'week'
这样POST请求会自动触发序列化器的create方法,实现“周数不存在则创建、存在则替换用户列表”的需求;PUT请求则通过update方法更新用户列表。
内容的提问来源于stack exchange,提问作者wardz
相关产品推荐
相关产品推荐

