Hi everyone,
I am trying to insert the parent
field as a ModelChoiceField
in a form, but I keep getting the error: “Select a valid choice. That choice is not one of the available choices.” This happens only for the parent
field, while other ModelChoiceField
fields like groups
and position
are working fine.
Also, in the views.py
, there’s a piece of code where I set the options for the parent
field, so there might be something wrong with it.
But in admin panel, it works fine.
Here is the models.py:
class NewUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('Emailová adresa'), unique=True, blank=False, null=False)
username = models.CharField(max_length=150, verbose_name='Přezdívka', unique=True, blank=False, null=False)
first_name = models.CharField(max_length=150, verbose_name='Křestní jméno', blank=False, null=False)
last_name = models.CharField(max_length=150, verbose_name='Příjmení', blank=False, null=False)
permanent_address = models.CharField(max_length=250, verbose_name='Adresa bydliště', blank=False, null=False)
cin = models.IntegerField(validators=[MaxValueValidator(99999999)], verbose_name='IČ', blank=False, null=False)
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, related_name='children', verbose_name='Rodič')
position = models.ForeignKey(Position, on_delete=models.SET_NULL, max_length=250, verbose_name='Pracovní pozice', blank=True, null=True)
start_date = models.DateTimeField(default=timezone.now, blank=False, null=False)
last_login = models.DateTimeField(default=timezone.now, blank=False, null=False)
date_joined = models.DateTimeField(default=timezone.now, blank=False, null=False)
is_staff = models.BooleanField(default=False, verbose_name='Člen administrace')
is_superuser = models.BooleanField(default=False, verbose_name='Superuživatel')
is_active = models.BooleanField(default=False, verbose_name='Aktivní')
groups = models.ManyToManyField('auth.Group', related_name='user_groups', blank=True, verbose_name='Skupiny')
objects = CustomAccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name', 'permanent_address', 'cin']
class Meta:
verbose_name = 'Uživatel'
verbose_name_plural = 'Uživatelé'
def get_groups(self):
groups = ", ".join([group.name for group in self.groups.all()])
return f"{groups}"
get_groups.short_description = "Skupiny"
def get_subordinates(self):
subordinate_users = []
subordinates = list(self.children.all())
for subordinate_user in subordinates:
subordinate_users.append(subordinate_user)
subordinate_users.extend(subordinate_user.get_subordinates())
return subordinate_users
def get_parents(self):
parent_users = []
parent_user = self.user.parent
while parent_user:
parent_users.append(parent_user)
parent_user = parent_user.parent
return parent_users
def __str__(self):
return f"{self.first_name} {self.last_name}"
forms.py:
class CreateNewUserForm(UserCreationForm):
class Meta:
model = NewUser
fields = ['email', 'first_name', 'last_name', 'cin', 'permanent_address', 'groups', 'position', 'parent',]
widgets = {
'email': forms.EmailInput(attrs={'class': 'form-control mb-1'}),
'first_name': forms.TextInput(attrs={'class': 'form-control mb-1'}),
'last_name': forms.TextInput(attrs={'class': 'form-control mb-1'}),
'cin': forms.NumberInput(attrs={'class': 'form-control mb-1'}),
'permanent_address': forms.TextInput(attrs={'class': 'form-control mb-1'}),
}
error_messages = {
'cin': {
'max_value': 'Maximálně je povoleno 8 čísel.'
}
}
groups = forms.ModelChoiceField(
queryset=Group.objects.all(),
widget=forms.Select(attrs={'class': 'form-select mb-1'}),
required=True,
label='Oprávnění',
empty_label=None
)
position = forms.ModelChoiceField(
queryset=Position.objects.all(),
widget=forms.Select(attrs={'class': 'form-select mb-1'}),
required=True,
label='Pracovní pozice',
empty_label=None
)
parent = forms.ModelChoiceField(
queryset=NewUser.objects.none(),
widget=forms.Select(attrs={'class': 'form-select mb-1'}),
required=True,
label='Nadřízený',
empty_label=None
)
password1 = forms.CharField(label="Heslo", widget=forms.PasswordInput(attrs={'class': 'form-control mt-1'}))
password2 = forms.CharField(label="Heslo pro ověření", widget=forms.PasswordInput(attrs={'class': 'form-control mt-1'}))
And views.py:
@login_required
def user_management(request):
create_new_user_form = CreateNewUserForm()
create_new_position_form = CreatePositionForm()
print(request.POST)
if request.method == 'POST':
print("POST request")
create_new_user_form = CreateNewUserForm(request.POST)
if create_new_user_form.is_valid():
print("Formulář je platný")
create_new_user_form.save()
messages.success(request, 'Uživatel úspěšně vytvořen.')
return redirect('index')
else:
print(create_new_user_form.errors)
messages.error(request, 'Nastala chyba.')
if request.user:
current_user = request.user
subordinates_list = current_user.get_subordinates()
subordinates_list.append(current_user)
# Seznam hodnot a popisků pro parent (choices)
choices = ((int(subordinate.pk), str(subordinate)) for subordinate in subordinates_list)
# Nastavíme choices pro parent field
create_new_user_form.fields['parent'].choices = choices
return render(request, 'dashboard/user_management/user_management.html', {
'current_user': request.user,
'subordinates': request.user.get_subordinates(),
'positions': Position.objects.all(),
'create_new_user_form': create_new_user_form,
'create_new_position_form': create_new_position_form,
})