Home > Blockchain >  Django User Form Update with Groups
Django User Form Update with Groups

Time:03-20

I am trying to update a User with django forms. In that form, I include UserGroups also. The problem right now I am facing is that

  • if the user has multiple groups or has no group at all, it is not working. but if the user has a single group then it is working fine. Here is my code.

views.py

class User(AbstractUser): 
    first_name = models.CharField(blank=False, max_length=25, null=False)
    last_name = models.CharField(blank=False, max_length=25, null=False)
    email = models.EmailField(blank=False, null=False, unique=True)
    password = models.CharField(blank=False, editable=False, max_length=256)
    company = models.ForeignKey(blank=True, on_delete=models.CASCADE, null=True, related_name="users", related_query_name="user", to='company.Company')
    is_active = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    username = name = contact = photo = None
    objects = UserManager()

    class Meta:
        ordering = ['id']

    def get_absolute_url(self):
        return reverse('user_detail', kwargs={'pk': self.pk})

    def __str__(self) :
        return self.email

forms.py

class UserForm(forms.ModelForm):
    company = forms.ModelChoiceField(queryset=Company.objects.all(), required=True)
    group = forms.ModelMultipleChoiceField(queryset=Group.objects.all(), required=True)

    def __init__(self, *args, **kwargs):
        super(UserForm, self).__init__(*args, **kwargs)
        self.fields['first_name'].widget.attrs = { 'class': 'form-control form-control-sm', 'name': 'first_name', 'id': 'first_name', 'type': 'text'}
        self.fields['last_name'].widget.attrs = { 'class': 'form-control form-control-sm', 'name': 'last_name', 'id': 'last_name', 'type': 'text'}
        self.fields['email'].widget.attrs = { 'class': 'form-control form-control-sm', 'name': 'email', 'id': 'email', 'type': 'email', 'aria-describedby': 'emailFeedback' }
        self.fields['company'].widget.attrs = { 'class': 'form-select form-select-sm', 'name': 'company', 'id': 'comapny', 'type': 'select' }
        self.fields['group'].widget.attrs = { 'class': 'form-select form-select-sm', 'name': 'groups', 'id': 'groups', 'type': 'select' }
        self.fields['is_active'].widget.attrs = { 'class': 'form-check-input', 'name': 'is_active', 'id': 'is_active', 'type': 'checkbox' }

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'company', 'group', 'is_active')

views.py

class UserUpdateView(LoginRequiredMixin, UpdateView):
    model = User
    form_class = UserForm
    template_name = 'user/form.html'

    def get_initial(self):
        initial = super(UserUpdateView, self).get_initial()
        try:
            current_group = self.object.groups.get()
        except:
            # exception can occur if the edited user has no groups
            # or has more than one group
            pass
        else:
            initial['group'] = current_group.pk
        return initial
    
    def form_valid(self, form):
        self.object.groups.clear()
        self.object.groups.add(form.cleaned_data['group'])
        return super(UserUpdateView, self).form_valid(form)

CodePudding user response:

if the user has multiple groups or has no group at all, it is not working. but if the user has a single group then it is working fine. Here is my code.

This is the portion of your code that corresponds to the above:

current_group = self.object.groups.get()

queryset.get() throws an error when there are no objects to return, or there are multiple ones, because it is supposed to return one single object.

CodePudding user response:

I fixed this problem myself

I make a list to pass current groups and add it one by one in valid_form method using iterations.

class UserUpdateView(LoginRequiredMixin, UpdateView):
    model = User
    form_class = UserForm
    template_name = 'user/form.html'

    def get_initial(self):
        initial = super(UserUpdateView, self).get_initial()
        try:
            current_groups = self.object.groups.all()
        except:
            pass
        else:
            user_Groups = []
            for group in current_groups:
                group_obj = Group.objects.get(name=group.name)
                user_Groups.append(group_obj.pk)
            initial['group'] = user_Groups
        return initial
    
    def form_valid(self, form):
        print(form.cleaned_data['group'])
        if self.request.method == 'POST':
            self.object.groups.clear()
            for group in form.cleaned_data['group']:
                self.object.groups.add(group.id)            
        else:
            self.object.groups.clear()
            self.object.groups.add(form.cleaned_data['group'])
        return super(UserUpdateView, self).form_valid(form)

If anyone has a better solution then please update. I would like to make it the best.

  • Related