1

I keep getting "Select a valid choice. 'X' is not one of the available choices." where 'X' is the primary key of the profile when I submit the create team form after filling in team name, selecting game and team members.

I have been trying to create a form for a model that has ManyToMany Relationship with Profile model. I decided to use django-autocomplete-light after trying django-select2 package.

Here is my code so far

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    dob = models.DateField(unique=False, null=True, blank=True)

class Game(models.Model):
    name = models.CharField(max_length=128, unique=True)
    is_team_game = models.BooleanField(default=False)

    def __str__(self):
        return '{}'.format(self.name)

class Team(models.Model):
    name = models.CharField(max_length=100)
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    players = models.ManyToManyField(Profile, related_name='player_profiles')

views.py

class ProfileAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = Profile.objects.all()
        if self.q:
            qs = qs.filter(user__username__istartswith=self.q)
        return qs

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('autocomplete/profile/', views.ProfileAutocomplete.as_view(), name='profile-autocomplete'),
]

forms.py

from django import forms
from .models import Game, Profile, Team
from dal import autocomplete

class TeamForm(autocomplete.FutureModelForm):
    players = forms.ModelMultipleChoiceField(label='Team Members', 
                            queryset=Profile.objects.none(), 
                            widget=autocomplete.ModelSelect2Multiple(url='profile-autocomplete'))
    class Meta:
        model = Team
        fields = [
            'name', 'game', 'players'
        ]
    
    def __init__(self, *args, **kwargs):
        super(TeamForm, self).__init__(*args, **kwargs)
        self.fields['game'].queryset = Game.objects.filter(is_team_game=True)

create_team.html template

{% extends "website/base.html" %}
{% load crispy_forms_tags %}
{% block head %}
    {{ block.super }}
    {{ form.media }}
{% endblock head %}

{% block content %}
    <div class="content-section">
        {% include "website/helper_nav.html" %}
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Create Team</legend>
                {{ form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">CREATE</button>
            </div>
        </form>
    </div>
{% endblock content %}
Monu Yadav
  • 519
  • 2
  • 17

1 Answers1

1

So I changed widget for players field instead of overwriting the entire field for the form. Here is my updated forms.py that resolved this error

class TeamForm(forms.ModelForm):
    class Meta:
        model = Team
        fields = [
            'name', 'game', 'players'
        ]
        widgets = {
            'players': autocomplete.ModelSelect2Multiple(url='profile-autocomplete',
                                                        attrs={
                                                            'data-placeholder': 'Select Team Members',
                                                            'data-minimum-input-length': 4,
                                                            })
            }
    
    def __init__(self, *args, **kwargs):
        super(TeamForm, self).__init__(*args, **kwargs)
        self.fields['game'].queryset = Game.objects.filter(is_team_game=True)

As soon as I assign it a queryset I get the error that was generated previously.

Monu Yadav
  • 519
  • 2
  • 17