mark
mark

Reputation: 673

Form does not validate in Django

I have such a form as shown below. When I click the "Add" button instead of the notification that the fields are required I get an error:

DoesNotExist at /users/add-to-group/
Group matching query does not exist.

My form code

class AddUserToGroupForm(forms.ModelForm):
    group = forms.ModelChoiceField(queryset=Group.objects.all(), required=True)
    user = forms.ModelChoiceField(queryset=User.objects.all(), required=True)

    class Meta:
        model = User
        fields = ['group', 'user']

    def has_group(self, user, group_name):
        group1 = Group.objects.get(name=group_name)
        return True if group1 in user.groups.all() else False

    def clean(self):
        cleaned_data = super(AddUserToGroupForm, self).clean()
        g = Group.objects.get(name=cleaned_data.get('group'))
        g.user_set.add(cleaned_data.get('user'))
        if self.has_group(cleaned_data.get('user'), cleaned_data.get('group')):
            self.add_error('user', "This user is already in group.")
        return cleaned_data

Upvotes: 0

Views: 128

Answers (1)

catavaran
catavaran

Reputation: 45555

The cleaned_data contains the Group instance, not the name of the Group. So you shouldn't use this query:

Group.objects.get(name=cleaned_data.get('group'))

Just assign the group instance to the g variable:

g = cleaned_data.get('group')

The same issue you have in the has_group function. group_name argument is a Group. The code should be:

def has_group(self, user, group):
    return group in user.groups.all()

UPDATE: If the user don't choose any group or user on the form the the cleaned_data don't contain the group/user values. So you have to check this case in the clean() method:

def clean(self):
    cleaned_data = super(AddUserToGroupForm, self).clean()
    group = cleaned_data.get('group')
    user = cleaned_data.get('user')
    if group and user:
        if self.has_group(user, group)):
            self.add_error('user', "This user is already in group.")
    return cleaned_data

And you shouldn't call group.user_set.add(user) in the clean(). This call has to be invoked from the form's save() method.

Upvotes: 2

Related Questions