TitanFighter
TitanFighter

Reputation: 5074

Need advice on relations between models\tables

Right now I have two models (in the future could be more):

class UserProfile(models.Model):

    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    birth_date = models.DateField(_('birth date'), null=True, blank=True)


class TeamProfile(models.Model):

    user = models.ManyToManyField(UserProfile)
    name = models.CharField(_('company name'), max_length=30, blank=True)
    info = models.TextField(_('information'), max_length=500, blank=True)

Both of these Profiles should be able to select its kinds_of_sports+mastery, i.e. each User or Team can play few kinds of sports and have different mastery level respectively, like: Jim (Football->Pro, Volleyball->Newby).

Would it be correct to do something like:

class AbstractSports(models.Model):
    KINDS_OF_SPORTS = (
        (1, _('football')),
        (2, _('volleyball')),
        (3, _('hockey')),
    )

    MASTERY_CHOICES = (
        (1, _('newby')),
        (2, _('amateur')),
        (3, _('semi-pro')),
        (4, _('pro'))
    )

    kind_of_sport = models.IntegerField(_('kind of sport'), null=True, blank=True, choices=KINDS_OF_SPORTS)
    mastery = models.IntegerField(_('mastery'), null=True, blank=True, choices=MASTERY_CHOICES)

    class Meta:
        abstract=True

class UserSports(AbstractSports):
    user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)

class TeamSports(AbstractSports):
    team = models.ForeignKey(TeamProfile, on_delete=models.CASCADE)

or could there be a better way?

Upvotes: 0

Views: 38

Answers (1)

davidejones
davidejones

Reputation: 1949

I'll take a stab at this, i'm not sure how much of an improvement this is but its what started running through my head as i was reading your question..

I'm not sure of the differences or similarities of the team and user profiles are but you may want to make that into a single model and then have a type that defines if its a user or team. Then have a relationship to itself if you want to have a team with user profiles assigned to it.

class Profile(models.Model):
    PROFILE_TYPES = (
        ('USER', 'User'),
        ('TEAM', 'Team'),
    )
    type = models.CharField(max_length=4, choices=PROFILE_TYPES)
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    birth_date = models.DateField(_('birth date'), null=True, blank=True)
    user = models.ManyToManyField('Profile') #manytomany itself for teams that have profiles assigned to it
    name = models.CharField(_('company name'), max_length=30, blank=True)
    info = models.TextField(_('information'), max_length=500, blank=True)

Then just have a single sports model like you had and just relating back to the profile

class Sports(models.Model):
    KINDS_OF_SPORTS = (
        (1, _('football')),
        (2, _('volleyball')),
        (3, _('hockey')),
    )

    MASTERY_CHOICES = (
        (1, _('newby')),
        (2, _('amateur')),
        (3, _('semi-pro')),
        (4, _('pro'))
    )
    kind_of_sport = models.IntegerField(_('kind of sport'), null=True, blank=True, choices=KINDS_OF_SPORTS)
    mastery = models.IntegerField(_('mastery'), null=True, blank=True, choices=MASTERY_CHOICES)
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

Upvotes: 1

Related Questions