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.