Reputation: 233
I have two models (Group and Contact). A Group can have many Contacts and a Contact can be in many Groups.
I can create contacts but I can´t create groups right now.
When I validate form.is_valid() it returns false and the error I'm getting is
{'contacts': [ValidationError(['Enter a list of values.'])]}
What am I missing here?
models.py
class Contact(models.Model):
# Fields
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=32)
contacts = models.ManyToManyField(Contact, related_name='groups')
forms.py
class CreateGroupForm(ModelForm):
class Meta:
model = Group
fields = ["name", "contacts"]
widgets = {
'name': TextInput(attrs={
"placeholder" : "",
"class": "form-control"
}),
'contacts': Select(attrs={
"placeholder" : "",
"class": "form-control"
})
}
class CreateContactForm(ModelForm):
class Meta:
model = Contact
fields = "__all__"
widgets = {
'first_name': TextInput(attrs={
"placeholder" : "Nombre",
"class": "form-control"
}),
'last_name': TextInput(attrs={
"placeholder" : "Apellido",
"class": "form-control"
})
}
views.py
def create_group(request):
if request.method == "POST":
form = CreateGroupForm(request.POST)
if form.is_valid():
group = form.save(commit=False)
group.save()
else:
print(form.errors.as_data())
form = CreateGroupForm()
return render(request, 'create-group.html', {'form':form})
elif request.method == "GET":
form = CreateGroupForm(request.POST or None)
return render(request, "create-group.html", { 'form' : form})
Upvotes: 1
Views: 2260
Reputation: 476659
For a ManyToManyField
, it makes not much sense to use a Select
widget [Django-doc], since that selects only a single element, a SelectMultiple
widget [Django-doc] is constructed to select mulitple objects.
You should also take a look to the HTML form whether it indeed submits values for the contact
field. You can do that by inspecting the browser data.
Nevertheless, even if you get this working, by using commit=False
, the form can not save the many-to-many field. Indeed, in order to save records in a many-to-many field, first the Group
object should be saved, since the junction table [wiki] has ForeignKey
s to the Contact
and Group
, and thus these records need to be created first. It is also better not to construct a new Form
in case the form is not valid, since then the errors will be reported when you render that form:
def create_group(request):
if request.method == 'POST':
form = CreateGroupForm(request.POST)
if form.is_valid():
form.save() # ← no commit=False
return redirect('name-of-some-view')
# do not create a new form.
else:
form = CreateGroupForm()
return render(request, "create-group.html", { 'form' : form})
Note: In case of a successful POST request, you should make a
redirect
[Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.
Upvotes: 1