Home > Software design >  Django models relation
Django models relation

Time:11-30

The idea is that there are two models: Group and Player. My objective is that there are different Groups and each group has players. Each player can belong to one or more groups. Inside a group, each player has some points accumulated, but the same player can have different points accumulated in another group.

class Player(models.Model):
    username = models.CharField(max_length = 200)
    won_games = models.IntegerField(default=0)

class Point(models.Model):
    player = models.ForeignKey(Player, on_delete=models.PROTECT, related_name='points')
    val = models.IntegerField()
    group =  models.ForeignKey(Group, on_delete=models.PROTECT, related_name='points')

class Group(models.Model):
    id = models.CharField(max_length = 200)
    players = models.ManyToManyField(Player,related_name="groups")
    points = models.ManyToManyField(Point)

I am confused because I don't know how to make that a player has "x" points in group A (for example) and also has "y" points in group B. I want to be able to show the data of a group, for each group, show its members and their points.

CodePudding user response:

You can tell Django to use a custom model for the many to many relationship using through parameter in that field, this way:


class Player(models.Model):
    username = models.CharField(max_length = 200)
    won_games = models.IntegerField(default=0)


class Group(models.Model):
    id = models.CharField(max_length = 200)
    players = models.ManyToManyField(Player, related_name="groups", through='Point')


class Point(models.Model):
    player = models.ForeignKey(Player, on_delete=models.PROTECT, related_name='points')
    group =  models.ForeignKey(Group, on_delete=models.PROTECT, related_name='points')

Django docs include an example for this topic here: https://docs.djangoproject.com/en/4.1/topics/db/models/#extra-fields-on-many-to-many-relationships

CodePudding user response:

You probably need an intermediate table with an extra field. Something similar to this:

from django.db import models

class Player(models.Model):
    username = models.CharField(max_length = 200)
    won_games = models.IntegerField(default=0)

    def __str__(self):
        return self.username

class Group(models.Model):
    name = models.CharField(max_length=128)
    players= models.ManyToManyField(Player, through='Point')

    def __str__(self):
        return self.name

class Point(models.Model):
    player = models.ForeignKey(Player, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    point = models.IntegerField()

  • Related