I have a model "CustomUserGroup" which has a ManyToMany field with Django's User object passed:
class CustomUserGroup(models.Model):
custom_group_name = models.CharField(max_length=50,unique=True)
users= models.ManyToManyField(User)
class Meta:
verbose_name_plural = 'Custom Groups'
ordering = ['custom_group_name']
def __unicode__(self):
return self.custom_group_name
def __repr__(self):
return self.custom_group_name
def __str__(self):
return self.custom_group_name
Here is the corresponding form:
...
from ajax_select.fields import AutoCompleteSelectMultipleField
class GroupForm(forms.ModelForm):
class Meta:
model = CustomUserGroup
fields = ['custom_group_name','users',]
users = AutoCompleteSelectMultipleField('users', required=True, help_text=None)
I wanted all users to be able ot create a new CustomUserGroup object:
def index(request):
groups = CustomUserGroup.objects.all()
if request.method == 'POST':
form = GroupForm(request.POST)
if form.is_valid():
new_group = form.save(commit=False)
new_group.save()
return render(request, 'chat/new_group_created.html', {'group_name': new_group.custom_group_name})
else:
return HttpResponse('A group with such name already exists. Please return and change the group name.')
else:
form = GroupForm()
return render(request, 'chat/index.html', {'form': form, 'groups': groups})
My problem is that I think I haven't configured this field correctly, because every time I run the "room" view in my views.py, I get HttpResponse('You shall not pass'), no matter which users have been added to the group before.
def is_member(user,group): # a function to check some of the parameters
print(user)
print(group)
print(group.users.all())
return user in group.users.all() # and return T/F based on whether the current user is a member
def room(request, room_name):
current_user = request.user
context = {'room_name': room_name}
if CustomUserGroup.objects.filter(custom_group_name = room_name).exists():
group = CustomUserGroup.objects.get(custom_group_name=room_name)
if is_member(current_user,group):
return render(request, 'chat/room.html', context)
else:
return HttpResponse('You shall not pass')
else:
return render(request, 'chat/no_such_room.html', context)
print(user) -> works fine
print(group) -> this one too
print(group.users.all()) -> <QuerySet []>
Do you have an idea what could be wrong here?
Python 3.10.4, Django 4.1.6
The problems seems to be connected to the model itself, not the form or its widget, because even in the database there is no "users" column at all
In the documentation for the ModelForm
class' save()
method, it says that Django doesn't automatically save many-to-many data when you first use form.save(commit=False)
and then new_object.save()
(as opposed to form.save(commit=True)
). And that the solution is to run form.save_m2m()
after new_object.save()
.
So in your case, either use new_group = form.save(commit=True)
or:
new_group = form.save(commit=False)
new_group.save()
form.save_m2m()