You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:03:14