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

如何在Django Rest Framework中为模型配置多对多关系

没问题,我来帮你搞定这个多对多关联的设置!要实现站点和分类之间的多对多关系,咱们分两步来:先调整模型,再修改序列化器,这样就能完美实现你要的关联效果啦。

第一步:调整模型,建立多对多关系

在Django里,多对多关系只需要在其中一个模型里定义ManyToManyField即可,同时设置related_name来指定反向关联的名称,正好对应你需要的sites字段。咱们在Site模型里添加这个字段:

class Site(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=100)
    # 添加多对多字段,related_name指定分类反向关联站点的字段名
    categories = models.ManyToManyField('SiteCategory', related_name='sites')

class SiteCategory(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=100)

这里的related_name='sites'很关键:当你拿到一个SiteCategory实例时,可以直接通过category.sites获取所有关联的站点;而Site实例则能通过site.categories获取关联的分类,完全匹配你的需求场景。

第二步:修改序列化器,支持多对多关联的序列化/反序列化

因为你用的是HyperlinkedModelSerializer,需要显式定义多对多关联的字段,指定对应的视图名称(view_name),这样DRF才能生成正确的超链接。修改后的序列化器代码如下:

from rest_framework import serializers
from .models import Site, SiteCategory

class SiteSerializer(serializers.HyperlinkedModelSerializer):
    # 定义categories字段,关联到SiteCategory的详情视图
    categories = serializers.HyperlinkedRelatedField(
        many=True,
        view_name='sitecategory-detail',  # 要和你路由里的视图名称一致
        queryset=SiteCategory.objects.all()
    )

    class Meta :
        model = Site
        fields = ('id', 'name', 'created', 'categories')

class SiteCategorySerializer(serializers.HyperlinkedModelSerializer):
    # 定义sites字段,关联到Site的详情视图
    sites = serializers.HyperlinkedRelatedField(
        many=True,
        view_name='site-detail',  # 同样要和路由里的视图名称一致
        queryset=Site.objects.all()
    )

    class Meta:
        model = SiteCategory
        fields = ('id', 'name', 'created', 'sites')

小提示:

  • 如果你的需求是返回关联对象的主键而非超链接,把HyperlinkedRelatedField换成PrimaryKeyRelatedField就行,用法完全一致。
  • view_name必须和urls.py中对应视图的name参数匹配,如果你用DRF的DefaultRouter自动生成路由,默认的详情视图名称就是模型名-detail(比如site-detail、sitecategory-detail),刚好能匹配上面的设置。
额外补充:路由配置参考

为了让超链接正常工作,推荐用DefaultRouter来自动生成路由,示例代码如下:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import SiteViewSet, SiteCategoryViewSet

router = DefaultRouter()
router.register(r'sites', SiteViewSet)
router.register(r'categories', SiteCategoryViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

这样设置完后,你就能实现:

  • 创建站点时可关联多个分类,创建分类时也能关联多个站点
  • 获取站点详情会返回所有关联分类的超链接
  • 获取分类详情会返回所有关联站点的超链接

内容的提问来源于stack exchange,提问作者Szabolcs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:07:25