I want to get the selected choice from a ChoiceField in a view:
views.py
def myFormSubmitView(request):
...
if form.is_valid():
print("valid form")
blog_post = Blog_Post()
blog_post.title = form.cleaned_data["title"]
blog_post.body = form.cleaned_data["body"]
**blog_post.categories = form.cleaned_data["categories"]** [[[PROBLEM HERE]]]]
blog_post.save()
return HttpResponseRedirect(request.path_info)
models.py
class Category(models.Model):
name = models.CharField(max_length=30)
#fix plural
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.name
class Blog_Post(models.Model):
title = models.CharField(max_length=255)
author = models.ForeignKey(MyUser,on_delete=models.CASCADE)
image = models.ImageField(null=True,upload_to='static/blog')
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
categories = models.ManyToManyField("Blog_Post", related_name="posts")
def __str__(self):
return self.title
forms.py
from django.db import models
from django import forms
#model form
from blog.models import Blog_Post
from django.forms import ModelForm
class NewBlogForm(ModelForm):
title = models.CharField(max_length=150)
# sections ids
section_ids =(
(0, "section1"),
(1, "section2"),
(2, "section3"))
categories = forms.ChoiceField(choices=section_ids)
body = models.CharField(max_length=255)
image = models.ImageField(upload_to='static/blog/images/', error_messages = {'invalid':("Image files only")},)
class Meta:
model = Blog_Post
fields = ['title','categories','body','image']
def __str__(self):
return self.title
...
When I try to get the value of the chosen category from the form, and empty string is returned.
Supposedly it should return the chosen âsection_idâ value but it doesnât.
What am I doing wrong ?
Welcome @mabaashar !
Iâm confused by a couple of things in your post.
First
Your model is named Blog_Post
, however the form you are showing has:
mabaashar:
class Meta:
model = Post
Which is not the same model.
Also, in Blog_Post, you have:
But in your form you have:
With Blog_Post.categories
being a ManyToManyField, the form field should be a ModelMultipleChoiceField . (But since your model form is referencing a different model, Iâm not sure if this is a mismatch or not.)
Thank you for the reply,
I edited the original code; I changed the code before copying it here thatâs why.
This still isnât right, is it? Are other instances of Blog_Post
what youâre looking to relate here?
I am trying to link the âchoiceâ to âcategoriesâ in the âsection_idsâ variable. But my selection results to empty.
But what does this have to do with a ManyToManyField in the model?
To do this (select the choice in the section_ids) values, then the model field would be a CharField, not a relationship.
It results in a dropdown with the blog âcategoriesâ to choose from, everything works but the selection is an empty string in views.
Correct, because you have a mismatch between the type of field and the data being used.
1 Like
revising code, thank you tons for answering
it is unneccesary set fields attrs because you use modelform.
just set fields.
and you add setion_ids attr, but it is not in model attr.
so, even if you add setion_ids model wonât be use that value.
from blog.models import Blog_Post
from django.forms import ModelForm
class NewBlogForm(ModelForm):
#title = models.CharField(max_length=150)
# sections ids
#section_ids =(
#(0, "section1"),
#(1, "section2"),
#(2, "section3"))
#categories = forms.ChoiceField(choices=section_ids)
#body = models.CharField(max_length=255)
#image = models.ImageField(upload_to='static/blog/images/', error_messages = {'invalid':("Image files only")},)
class Meta:
model = Blog_Post
fields = ['title','categories','body','image']
def __str__(self):
return self.title
...
if you want custom choice, set widgets.
from django.forms import models
class NewBlogForm(ModelForm):
...
class Meta:
widgets = {
'categories': models.ModelChoiceField(queryset={category queryset})
}
...
1 Like
Ů I have changed the type of âcategories â in âmodels.py â to categories = models.ForeignKey(Category,on_delete=models.CASCADE
ForeignKey is more suitable as you hinted to the wrong type @KenWhitesell
But it throws me a new ValueError now:
Cannot assign ââ1ââ: âPost.categoriesâ must be a âCategoryâ instance.
The value 1 is chosen from the âsection_idsâ fed to the ChoiceField variable in forms.py
If Blog_Post.categories
is a ForeignKey, the form field should be a ModelChoiceField .
I donât understand why youâre trying to set this to a defined constant when the values need to exist in the referenced model.
1 Like
Now it worked probably ! thank you so much : )
For anybody reading the answer is not âForeignkeyâ but âmodelchoicefieldâ representing the Category model.
Thank you for your answer; I will also add the widget attribute to the modelForm right now.