Dropdown field in FormView based on model data

I have a FormView that has a field

forms.CharField(label='Team', widget=forms.Select(choices=TEAM_CHOICES), required=False)

TEAM_CHOICES is populated like this:

TEAM_CHOICES = [(None, 'Select a Team')]
for team in Team.objects.filter(sport=1):
    TEAM_CHOICES.append((team.mlb_api_team_id, team.name))

The purpose of the TEAM_CHOICES list is to populate a dropdown list in a search form. Although MLB teams rarely change (and that’s all I’m doing right now), I want to be able (at some future point) to include lower division teams and they DO change with regularity.

When I am on my development environment with Postgres it works fine. I can make new migrations and run them to my heart’s content.

However, when I try to push my code CI/CD (using GitHub Actions) I get the following error:

django.db.utils.ProgrammingError: relation "team_team" does not exist
98
LINE 1: ...team"."league_id", "team_team"."division_id" FROM "team_team...

This is because the table team_team hasn’t been created in the Ubuntu container that GitHub Actions is spinning up. In order to get around this issue I added the following try/except:

TEAM_CHOICES = [(None, 'Select a Team')]
ver = None
database = DATABASES['default']['NAME']
user = DATABASES['default']['USER']
password = DATABASES['default']['PASSWORD']
port = DATABASES['default']['PORT']
host = DATABASES['default']['HOST']

con = psycopg2.connect(database=database, user=user, password=password, host=host)
cur = con.cursor()
try:
    cur.execute('select exists(SELECT 1 from team_team)')
    ver = cur.fetchone()
except psycopg2.Error:
    pass
if ver:
    for team in Team.objects.filter(sport=1):
        TEAM_CHOICES.append((team.mlb_api_team_id, team.name))

All of this feels wrong though. I think I’m trying to approach this particular problem from a non-Django perspective, but I’m not really sure what the Django way would be.

For now, I am just getting the data I need and populating it without the Team model.

Any input would be greatly appreciated!

In general, when I have a situation like this, I would define the team option as a ForeignKey to a Team table instead of trying to use the “TEAM_CHOICES”-type solution. That avoids a lot of the options manipulations you’re having to do.

As far as populating it, then my Team table could be created with a migration, and the data being loaded with a fixture using the loaddata command.

It just “seems” like it would be easier to me than what you’re doing now. (And I could be completely wrong here…)

Ken

Thank you so much Ken! This is exactly what was needed. I’ve updated to remove the manually enumerated list with these Form Fields:

team_name = forms.CharField(label='Team', widget=forms.Select(choices=TEAM_CHOICES), required=False)
opp_name = forms.CharField(label='Opponent', widget=forms.Select(choices=TEAM_CHOICES), required=False)

To this:

team_name = forms.ModelChoiceField(label='Team', queryset=Team.objects.filter(sport=1), required=False)
opp_name = forms.ModelChoiceField(label='Opponent', queryset=Team.objects.filter(sport=1), required=False)

Thanks again for your help!