簡體   English   中英

如果有 2 個外鍵與 Django Rest 框架連接同一張表,如何序列化連接表?

[英]How to serialize joined tables if there are 2 Foreign Key to join the same table with Django Rest Framework?

我有一個簡短的 model 來存儲足球隊和他們的比賽結果。 比賽 model 有一個 home_team_id 和一個 away_team_id 來標識 2 支球隊,它們都是球隊 model 的外鍵。我想將這兩個表中的數據序列化為以下 output:

[
 {
        "home_team_id": 283584,
        "home_team_name": "FC Bayern München"
        "away_team_id": 61,
        "away_team_name": "Chelsea FC"
        "match_id": 12342
        "home_team_goals": 1,
        "away_team_goals": 2,
  },
  ...
]

模型.py

from django.db import models

class Team(models.Model): 
    team_id = models.IntegerField(primary_key=True)
    team_name = models.CharField(max_length=200, blank=False, null=False)
    #category_id = models.IntegerField(blank=False)
    #value = models.IntegerField(blank=False)

    def __str__(self):
        return '%s' % (self.team_name)

class Match(models.Model):
    match_id = models.IntegerField(primary_key=True)
    home_team_id = models.ForeignKey(Team, on_delete=models.CASCADE, related_name="home_team_id")
    away_team_id = models.ForeignKey(Team, on_delete=models.CASCADE, related_name="away_team_id")
    home_team_goals = models.SmallIntegerField(blank=False)
    away_team_goals = models.SmallIntegerField(blank=False)

視圖.py

@api_view(['GET'])
def full_list(request):
    full = Match.objects.all()
    serializer = TeamMatchesSerializer(full, many=True)
    return Response(serializer.data)

序列化程序.py

class TeamMatchesSerializer(serializers.ModelSerializer):
    team_name = serializers.StringRelatedField(many=True, read_only=True)
    class Meta:
        model = Match
        fields = ('match_id',  'home_team_goals', 'away_team_goals', 'team_name')

我收到一個錯誤:“匹配”object 沒有屬性“team_name”,這在 views.py 中是公平的,已選擇匹配 model,但是我添加了 team_name = serializers.StringRelatedField(many=True, read_only=True)序列化程序。 我嘗試了另一種方法,在序列化程序中使用團隊 model,基於此處的教程: https://www.django-rest-framework.org/api-guide/relations/ ,但它沒有用。 我什至不確定如何區分團隊名稱,因為它都使用團隊 model。

原始 SQL 這個查詢只是為了確保我的問題有意義:

select home.team_id,
       home.team_name,
       away.team_id,
       away.team_name,
       a.match_id,
       a.home_team_goals,
       a.away_team_goals
from api_match a
inner join api_team home on home.team_id = a.home_team_id
inner join api_team away on away.team_id = a.away_team_id

解決方案很簡單,只要您想在序列化程序中計算一些值,就可以使用serializers.SerializerMethodField() docs 在您的情況下,您可以將序列化程序定義為

class TeamMatchesSerializer(serializers.ModelSerializer):
    home_team_name = serializers.SerializerMethodField()
    away_team_name = serializers.SerializerMethodField()
    
    def get_home_team_name(self, obj):
        return obj.home_team_id.team_name
        
    def get_away_team_name(self, obj):
        return obj.away_team_id.team_name
          
    class Meta:
        model = Match
        fields = '__all__' 

另外,我這邊的一個建議是,在聲明外鍵字段的屬性名稱時,不要在末尾使用_id后綴,因為 ORM 已經為您完成了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM