Hi!
I’m in the process of creating a plant database that members should be able to comment on, update, and supplement with information.
I’m using M2M fields to classify and store unique attributes of each plant.
The structure of the data is built as follows:
SubCategory → Category
examples of content in subcategory/category
Green → Color
Red → Color
Yellow → Color
…
1,0 m → Height
1,5 m → Height
2,0 m → Height
2,5 m → Height
…
January-February → Fruit
February-March → Fruit
March-April → Fruit
My question concerns how to render the form. Each “Category” should be displayed as its own “CheckboxSelectMultiple,” where the associated “SubCategory” linked to the current “Category” is listed.
For example:
Category: Color - SubCategory: Red, Green, Yellow, …
I hope the question is clear and informative.
Any Help Appreciated!
# models.py
class Category(models.Model):
name = models.CharField(max_length=50)
@staticmethod
def get_all_categories():
return Category.objects.all()
def __str__(self):
return self.name
class SubCategory(models.Model):
name = models.CharField(max_length=50)
categories = models.ManyToManyField(Category, related_name='parent_categories')
def __str__(self):
#return self.name + str(self.get_category())
return self.name
def get_category(self):
return self.categories.first()
class Plant(models.Model):
name = models.CharField(max_length=60)
# ...
categorys= models.ManyToManyField(SubCategory, related_name='child_categories')
# ...
def __str__(self):
return self.name
def get_category_name(self):
parent = self.category.all()
category = parent.categories.first()
return category
``
# forms.py
class PlantForm (forms.ModelForm):
# How to generate form for example Color, Height, Fruit.
# Is it possible på dynamically generate form?
color = forms.ModelMultipleChoiceField(
SubCategory.objects.filter(categories__name="Color"), label="Color",
widget=forms.CheckboxSelectMultiple)
height = forms.ModelMultipleChoiceField(
SubCategory.objects.filter(categories__name="Height"), label="Height",
widget=forms.CheckboxSelectMultiple)
# ...
# Fruit
# ...
class Meta:
model = Plant
fields = "__all__"
#exclude = ["category"]
def save(self, commit=True):
# do something with self.cleaned_data['color']
# How to handle extra form from M2M field.
# This code doesn't work
subform_color = SubCategory(self.cleaned_data['color'])
subform_color().save
subform_height = SubCategory(self.cleaned_data['height'])
subform_height().save
return super(PlantForm, self).save(commit=commit)
# views.py
class PlantDetailView(DetailView):
model= Plant
context_object_name = 'plant'
form = PlantForm()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.form
# How to handle the this?
context['categorys'] = Category.objects.all()
context['sub_categorys'] = SubCategory.objects.all()
return context
def post(self, request, *args, **kwargs):
form = PlantForm(request.POST)
if form.is_valid():
post = self.get_object()
# How to handle the this?
# form.instance.name = request.POST.get('name', '')
# form.instance.user = self.request.user
# form.save()
return redirect(reverse("ProductsDetailView", kwargs={'pk': post.pk}))