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.
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})
}
...
Ů 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.
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.