Django Rest为每个项返回相关的项



我试图在类似的问题中找到答案,但没有一个符合我的期望。

我有两个模型:

class Artist(models.Model):
    name = models.CharField(max_length=255)
    music_type = models.CharField(max_lenght=50)
    def __str__(self):
        return self.name
class Event(models.Model):
    event_name = models.CharField(max_length=255)
    ...
    artists = models.ManyToManyField(Artist)
    def __str__(self):
        return self.event_name

我也有serializers.py文件:

class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
        fields = '__all__'

class ArtistSerializer(serializers.ModelSerializer):
    events = EventSerializer(source='event_set', many=True)
    class Meta:
        model = Artist
        fields ='__all__'

ArtistSerializer中的event允许我返回艺术家参加的所有活动。现在,对于每个艺术家,我想获得所有艺术家的列表,如果他们曾经参加过同一个活动。

例如,我有5个艺术家(A1…A5)和3个事件(E1…E3)事件1:[A1,A3]

In Event 2: [A3,A4,A5,A2]

In Event 3: [A2, A3]

So for A3 I would like to get list [A1,A4,A5,A2]
For A1: [A3]
For A2: [A3,A4,A5]

不幸的是,我在创建这个查询时遇到了巨大的问题,因为sql -查询和ORM机制在这种情况下看起来更复杂。有人能帮我解决这个问题吗?或者给点提示如何解决这个问题?

如果需要,我会分享更多的代码

您可以查询through模型以获取与事件相关的艺术家。这是django创建的中间模型,用来建立M2M关系。

如果你有一个ManyToManyField,它有一个through的属性,这是M2M模型。

所以从你的事件模型中,你可以做像Event.artists.through.objects.all()这样的事情,你会看到你的M2M模型中的所有实例。

所以要找出与给定事件相关的艺术家你可以查询同一个表;

Event.artists.through.objects.filter(event_id=1).select_related('artist')

返回M2M中属于事件1的所有对象。然后你可以从那里获取艺术家,或者直接获取艺术家id Event.artists.through.objects.filter(event_id=1).values_list('artist_id, flat=True)

考虑到你评论中的场景…

如果你有一个艺术家,那么你可以运行一个查询来获取他们曾经参与过的事件,然后运行另一个带有这些事件id的查询。在第二个查询中,您要查找的艺术家id不是当前正在查看的艺术家。

# First get the events that the current artist has been in
event_ids = Event.artists.through.objects.filter(artist_id=1).values_list('event_id, flat=True)
# Then get the other artists who have been in the same events
other_artist_ids = Event.artists.through.objects.filter(event_id__in =event_ids).exclude(artist_id=1).values_list('artist_id, flat=True)
# or the full instances
other_artists = Event.artists.through.objects.filter(event_id__in =event_ids).exclude(artist_id=1).select_related('artist')

相关内容

  • 没有找到相关文章

最新更新