Django Обновление формы пользователя с помощью групп

Я пытаюсь обновить пользователя с помощью формы django. В этой форме я также включаю UserGroups. Проблема, с которой я сейчас столкнулся, заключается в том, что

  • если у пользователя несколько групп или вообще нет группы, это не работает. Но если у пользователя одна группа, то все работает нормально. Вот мой код.

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)

если у пользователя несколько групп или вообще нет группы, то это не работает. но если у пользователя одна группа, то все работает нормально. Вот мой код.

Вот часть вашего кода, которая соответствует приведенному выше:

current_group = self.object.groups.get()

queryset.get() выдает ошибку, если нет объектов для возврата, или их несколько, поскольку предполагается, что возвращается один единственный объект

Я сам устранил эту проблему

Я составляю список для передачи текущих групп и добавляю их по одной в метод valid_form, используя итерации.

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)

Если у кого-то есть лучшее решение, пожалуйста, обновите его. Я хотел бы сделать его лучшим.

Вернуться на верх