In the documentation, is there a way to override this behavior?
i.e. I want car.built_by
to return a model instance i.e. <Manufacturer: Toyota>
rather than a primary key since I need to maintain the foreign key relationship while annotating.
Update:
I'm currently developing a basketball stats website. I have the following models:
# models.py
class Game(models.Model):
league = models.ForeignKey('League', ...)
tournament = models.ForeignKey('Tournament', ...)
home_team = models.ForeignKey('Team',...)
away_team = models.ForeignKey('Team',...)
home_pts = models.IntegerField()
away_pts = models.IntegerField()
class Team(models.Model):
team_name = models.CharField()
team_code = models.CharField()
team_nickname = models.CharField()
def __str__(self):
return f'{self.team_name} {self.team_nickname}'
I'm using django-tables2 to populate the table of a Team's schedule for a particular tournament. So I do the following query:
Game.objects.filter(tournament_id=/insert_tournament_id_here/).filter(Q(home_team_id=self.id) | Q(away_team_id=self.id))
that gives me the Games of the Team. My problem is that when I'm populating the views.py of the team schedule, I want it to be "Opponent" rather than "Home Team" and "Away Team". So I decided to do this:
Team_Game_Queryset.annotate(opponent=Case(When(home_team=/team_id/, then=F('away_team')), default=F('home_team'), output_field=ForeignKey('myapp.Team'))
my problem is that, the annotated column "opponent" isn't a ForeignKey reference for the Team model, so I can't use the str representation of the object. I was able to do this by converting the QuerySet into a pandas DataFrame and then returning a dictionary (which is an easy read into django-tables2). But I always prefer to return a QuerySet to django-tables rather than a dict, and I was wondering if there was any way to overwrite the F() behavior, or if there's any other way to do this using QuerySets.
Since you've said you're using django-tables2, I'm assuming you have a table class
# tables.py
import django_tables2 as tables
class Game Table(tables.Table):
opponent = tables.Column()
class Meta:
model = Game
def __init__(self, team_id, *args, **kwargs):
super().__init__(*args, **kwargs)
def render_opponent(self, record):
return record.home_team if record.away_team_id == self.team_id else record.away_team
# views.py
def list_team_games(request):
query_set = Game.objects.filter(tournament_id=/insert_tournament_id_here/).filter(Q(home_team_id=self.id) | Q(away_team_id=self.id))
table = GameTable(self.id, queryset)
return render(request, 'game_list.html', {
'table': table
})
Note that I have added a opponent
column and written a render_opponent
method on the table. (Refer to the docs)
I personally have never used django-tables2, but this is what I put together by reading the tutorial in the documentation