如何通过链接到另一个模型的外键访问模型字段?

时间:2019-01-05 15:39:03

标签: python django django-rest-framework

我有一个包含一个用户的模型,每个用户都与一个俱乐部关联,一个俱乐部可以包含许多团队,球场等。我想知道如何设计模型,以便可以在团队中显示/编辑信息/ pitch基于已登录的用户以及与该用户关联的俱乐部。我的ClubInfo模型包含与用户相关联的外键,而我的其他模型(团队/音高)具有与ClubInfo而非用户相关联的外键。

class ClubInfo(models.Model):

user = models.OneToOneField(User, on_delete=models.CASCADE)
club_name = models.CharField(max_length=50, default='')
club_logo = models.ImageField(upload_to='profile_pics', blank=True)
club_address1 = models.CharField(max_length=30)
club_address2 = models.CharField(max_length=30, default='')
club_address3 = models.CharField(max_length=30, default='')
club_town = models.CharField(max_length=30)
club_county = models.CharField(max_length=30)
club_country = models.CharField(max_length=30)

def __str__(self):
    return self.club_name



class Player(models.Model):

club_name = models.ForeignKey(ClubInfo, to_field='id', on_delete=models.CASCADE, unique=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
dob = models.DateField(max_length=8)
email = models.EmailField(max_length=50)
phone = models.CharField(max_length=12)
mobile = models.CharField(max_length=15)
emergency_contact_name = models.CharField(max_length=40)
emergency_contact_mobile = models.CharField(max_length=15)
address1 = models.CharField(max_length=30)
address2 = models.CharField(max_length=30, default='')
address3 = models.CharField(max_length=30, default='')
town = models.CharField(max_length=30)
county = models.CharField(max_length=30)
country = models.CharField(max_length=30)

def __str__(self):
    return "%s %s" % (self.first_name, self.last_name)


class Team(models.Model):

club_name = models.ForeignKey(ClubInfo, to_field='id', on_delete=models.CASCADE, unique=True)
team_name = models.CharField(max_length=30)
manager_name = models.CharField(max_length=20)
player_pk = models.ForeignKey(Player, to_field='id', on_delete=models.CASCADE, unique=True)

def __str__(self):
    return self.team_name


class Pitch(models.Model):
club_name = models.ForeignKey(ClubInfo, to_field='id', on_delete=models.CASCADE, unique=True)
pitch_name = models.CharField(max_length=30)
PITCH_SIZES = (
    ('S', 'Small'),
    ('M', 'Medium'),
    ('L', 'Large'),
)
PITCH_TYPE = (
    ('1', 'Outdoor'),
    ('2', 'Indoor'),
)
pitch_size = models.CharField(max_length=1, choices=PITCH_SIZES)
pitch_type = models.CharField(max_length=1, choices=PITCH_TYPE)
open_time = models.TimeField(default='09:00')
close_time = models.TimeField(default='22:00')

def __str__(self):
    return self.pitch_name

2 个答案:

答案 0 :(得分:0)

  1.   

    俱乐部可以包含许多球队,球场等。

那么您可能不想在外键中使用unique=True, 因为该行为与OneToOneField非常相似。那意味着 每个俱乐部只能有一个球员,一个球场等。

请参考: What's the difference between django OneToOneField and ForeignKey?

  1. 您无需显式编写to_field='id',这是to_field参数的默认值

https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.to_field

  1.   

    以便我可以根据登录的用户显示/编辑有关团队/场地的信息

您需要定义反向关系: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name

例如:

class Pitch(models.Model):
    club_name = models.ForeignKey(ClubInfo, on_delete=models.CASCADE, related_name="pitches")
    (...)

然后您可以通过以下方式查询玩家的音高:

player = Player.objects.get(<get your player>).club_name.pitches
  1. 在您当前的设计中(删除unique=True之后),团队可以组成 只能有一名球员,而且球员可以在许多团队中。那是预期的吗? 您最有可能想要拥有

1)与许多玩家组成团队-那么您需要在Team模型中向Player添加外键

2)团队中有很多球员,但球员也可以在很多团队中-那么您希望建立多对多关系: https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/

  1. club_name作为外键是一个不好的命名约定-它并不指向club_name,而是指向Club对象

答案 1 :(得分:0)

club = ClubInfo.objects.filter()

blog = Player.objects.filter(Q(club_name__in=club))