nutship
nutship

Reputation: 4924

Django model with relationships

I know, questions of this kind have been asked at least a bunch of times here, but I am kind of starting with django and I am having a tough time to apply solutions from similar questions and just put this stuff together.

I think my model should have 3 classess:

class Guild(models.Model):
    name = models.CharField(max_length=50)

class Battle(models.Model):
    guild1 = models.ForeignKey(Guild, related_name="guild_one")
    guild2 = models.ForeignKey(Guild, related_name="guild_two")
    # tournament = models.ForeignKey(Tournament) ???

class Tournament(models.Model):
    name = models.CharField(max_length=50)
    ????

A Battle is a war between two Guilds and takes place during a Tournament. There can be many Battles in a Tournament. A Guild can participate in several Tournaments.

I want to be able to search by Guild (to see every Battle of theirs, from every Tournament they have taken part in), by Tournament to see what Battles have been played out plus I would like to have access through Tournament to see which Guilds have ever participated. Will the above code (plus the line I commeneted out) work, because I feel like maybe Tournament class should have reference to Battle?

Also, if you could give an example of a query that will take all Guilds' names that participated in a given Tournament.

Upvotes: 0

Views: 199

Answers (1)

miikkas
miikkas

Reputation: 818

The model Battle is a fine place for having the foreign key to a tournament, so you can remove the comment, although you should use the quotation marks for referencing to the Tournament, since it's declared after the Battle, i.e. models.ForeignKey('Tournament').

To get all the participating guilds' names in a list format, use the backwards relation objects guild_one and guild_two of the Guild object, the Q objects and the .values_list(). Like this:

>>> from django.db.models import Q
>>> Guild.objects.filter(Q(guild_one__tournament=t) |\
... Q(guild_two__tournament=t)).values_list('name', flat=True)
[u'red', u'blue', u'green', u'black']

Assuming that t references to some Tournament.

Upvotes: 3

Related Questions