【问题标题】:Django Rest - get related data in M2M relationDjango Rest - 获取 M2M 关系中的相关数据
【发布时间】:2021-04-21 13:59:16
【问题描述】:

我有 2 个模型:

class Artist(models.Model):
    name = models.CharField(max_length=255)
    music_type = models.CharField(max_length=50)

class Event(models.Model):
    event_name = models.CharField(max_length=255)
    description = models.TextField()
    place = models.CharField(max_length=50)
    longitude = models.DecimalField(max_digits=9, decimal_places=6)
    latitude = models.DecimalField(max_digits=9, decimal_places=6)
    date = models.DateField()
    artists = models.ManyToManyField(Artist)

对于每一位艺术家,如果他们曾经一起参加过任何活动,我想获得其他艺术家的名单。

我能够创建封闭的解决方案,但仅限于特定的艺术家:

def get_related_artists(request):

    artist_id = 2
    related_events = Artist.objects.filter(id=artist_id).first().event_set.all()
    related_artists_ids = []
    for event in related_events:
        related_artists_ids = related_artists_ids + list(event.artists
                                                     .all()
                                                     .values_list('id', flat=True)
                                                     .all())
    related_artists = Artist.objects\
    .filter(id__in=set(related_artists_ids))\
    .exclude(id=artist_id)

    serializer = ArtistRelatedSerializer(related_artists, many=True)
    return JsonResponse(serializer.data, safe=False)

所以首先我得到了特定艺术家参加的所有活动。后来我遍历这些事件并获取其他艺术家的 ID。另一个步骤是删除重复的 ID 和特定的艺术家 ID。最后我使用序列化器返回数据。

序列化器看起来像:

class ArtistRelatedSerializer(serializers.ModelSerializer):

    class Meta:
        model = Artist
        fields = '__all__'

不幸的是,我认为这不是最佳解决方案,仅适用于硬编码的艺术家 ID。我想获取所有艺术家和其他艺术家的 ech 列表。 我正在考虑创建循环并迭代 Artist.objects.count(),但我找不到一个可靠的解决方案来维护所有这些查询。

还有其他更简单的方法来解决这个问题吗?

【问题讨论】:

    标签: django-rest-framework django-queryset django-orm


    【解决方案1】:

    您可以使用 SerializerMethodField 从 Serializer 解决此问题。获取每个 Artist 中的所有事件,示例如下:

    class ArtistSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Artist
            fields = ('id', 'name', 'music_type', 'events')
    
        events = serializers.SerializerMethodField()
    
        def get_events(self, obj):
            events_qs = Event.objects.filter(artists__in=[obj.id])
            events = EventSerializer(
                events_qs, many=True, context=self.context).data
            return events
    

    为避免圆形导入错误,您应该在函数中使用import

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2015-12-23
      • 1970-01-01
      相关资源
      最近更新 更多