2

First of all I have to admit that I'm quite new to all this coding stuff but as I couldn't find a proper solution doing it myself and learning to code is probably the best way.

Anyway, I'm trying to build an app to show different titleholders, championships and stuff like that. After reading the Django documentation I figured out I have to use intermediate models as a better way. My old models.py looks like this:

class Person(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    [...]

class Team(models.Model):
    name = models.CharField(max_length=64)
    team_member_one = models.ForeignKey(Person)
    team_member_two = models.ForeignKey(Person)

class Championship(models.Model):
    name = models.CharField(max_length=128)
    status = models.BooleanField(default=True)

class Titleholder(models.Model):
    championship = models.ForeignKey(Championship)
    date_won = models.DateField(null=True,blank=True)
    date_lost = models.DateField(null=True,blank=True)
    titleholder_one = models.ForeignKey(Person,related_name='titleholder_one',null=True,blank=True)
    titleholder_two = models.ForeignKey(Person,related_name='titleholder_two',null=True,blank=True)

Championships can be won by either individuals or teams, depending if it's a singles or team championship, that's why I had to foreign keys in the Titleholder class. Looking at the Django documentation this just seems false. On the other hand, for me as a beginner, the intermediate model in the example just doesn't seem to fit my model in any way.

Long story short: can anyone point me in the right direction on how to build the model the right way? Note: this is merely a question on how to build the models and displaying it in the Django admin, I don't even talk about building the templates as of now.

Help would be greatly appreciated! Thanks in advance guys.

Everlong
  • 31
  • 4
  • 1
    Django's `ManyToManyField` is just syntactic sugar for automatically creating and querying an intermediate table. If you create the table explicitly, as you've sort of done here, then you don't need the field (although it can still be helpful). However, there are a number of problems with the schema you've presented. None of them have anything to do with Django, it's a question of SQL database modeling. I suggest asking a more general question (*how can I model this data? here's what I've tried...*) and tagging it with [tag:database-design] or [tag:data-modeling]. – Kevin Christopher Henry May 03 '16 at 18:20

1 Answers1

0

So I will take it up from scratch. You seem to be somewhat new to E-R Database Modelling. If I was trying to do what you do, I would create my models the following way.

Firstly, Team would've been my "corner" model (I use this term to mean models that do not have any FK fields), and then Person model would come into play as follows.

class Team(models.Model):
    name = models.CharField(max_length=64)

class Person(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    team = models.ForeignKey(to=Team, null=True, blank=True, related_name='members')

This effectively makes the models scalable, and even if you are never going to have more than two people in a team, this is good practice.

Next comes the Championship model. I would connect this model directly with the Person model as a many-to-many relationship with a 'through' model as follows.

class Championship(models.Model):
    name = models.CharField(max_length=64)
    status = models.BooleanField(default=False) # This is not a great name for a field. I think should be more meaningful.
    winners = models.ManyToManyField(to=Person, related_name='championships', through='Title')

class Title(models.Model):
    championship = models.ForeignKey(to=Championship, related_name='titles')
    winner = models.ForeignKey(to=Person, related_name='titles')
    date = models.DateField(null=True, blank=True)

This is just the way I would've done it, based on what I understood. I am sure I did not understand everything that you're trying to do. As my understanding changes, I might modify these models to suit my need.

Another approach that can be taken is by using a GenericForeignKey field to create a field that could be a FK to either the Team model or the Person model. Or another thing that can be changed could be you adding another model to hold details of each time a championship has been held. There are many ways to go about it, and no one correct way.

Let me know if you have any questions, or anything I haven't dealt with. I will try and modify the answer as per the need.

srthu
  • 197
  • 2
  • 14