我正在尝试复制产品发布时使用的类似Ebay的类别结构网站。例如,如果要发布Iphone进行销售,则要发布广告,从表单的下拉菜单中选择一个类别(“电子和计算机”),然后选择“电话”子类别,然后选择“ iphone”的最后一个子类别。为了创建这种结构,我使用了django-categories。在管理页面工作文件中创建产品,管理表单允许我从每个类别的下拉菜单中进行选择,但是我似乎无法在自己的表单上复制相同的过程,从而使用户能够从中进行选择许多类别。
如果您不知道django-categories是否为修改的预排序树遍历。
这是我的广告模特
class Advert(models.Model):
title = models.CharField(max_length=100, blank=False, null=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
image = models.ImageField(upload_to='media/', blank=True, null=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(blank=False, null=False)
condition = models.CharField(max_length=10, choices=COND_CATEGORIES, blank=False, null=False)
price = models.DecimalField(decimal_places=2, max_digits=14, blank=False, null=False)
description = models.TextField(blank=False, null=False)
date_posted = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
search_vector = SearchVectorField(null=True, blank=True)
这里是类别模型
class Category(CategoryBase):
class Meta:
verbose_name_plural = 'categories'
这里是允许用户发布广告的表格
class PostAdvertForm(forms.ModelForm):
title = forms.CharField(label='Ad Title', required=True)
category = forms.ChoiceField(choices=Advert.category, label='Choose a category', required=True)
price = forms.DecimalField(label='Price', required=True, widget=forms.TextInput())
description = forms.CharField(widget=forms.Textarea(attrs={'placeholder':
('Please provide a detailed description'),
'autofocus': 'autofocus'}), label='Description', required=True)
condition = forms.ChoiceField(choices=Advert.COND_CATEGORIES, label='Condition', required=True)
quantity = forms.IntegerField(label='Quantity', required=True, widget=forms.TextInput())
image = forms.ImageField(label='Upload an image', required=False)
class Meta:
model = Advert
fields = (
'title', 'category', 'quantity', 'condition', 'price', 'description',
'image')
由于“ ForwardManyToOneDescriptor'对象不可迭代,因此在选择字段上使用advert.category无法正常工作”。
我的问题是如何使类别列表显示在选择字段上?
编辑:只是想知道,这是否有可能完全在前端使用jquery来实现,并通过清除的数据通过选择的类别发送?这样,我什至无需在后端使用django-categories,我可以存储大量的类别。
第二编辑:
看起来我已经完成了第一部分工作,我在下面粘贴了新的表单代码:
at = Advert.category.get_queryset()
class PostAdvertForm(forms.ModelForm):
title = forms.CharField(label='Ad Title', required=True)
category = forms.ModelChoiceField(queryset=cat, label='Choose a category', required=True)
price = forms.DecimalField(label='Price', required=True, widget=forms.TextInput())
description = forms.CharField(widget=forms.Textarea(attrs={'placeholder':
('Please provide a detailed description'),
'autofocus': 'autofocus'}), label='Description', required=True)
condition = forms.ChoiceField(choices=Advert.COND_CATEGORIES, label='Condition', required=True)
quantity = forms.IntegerField(label='Quantity', required=True, widget=forms.TextInput())
image = forms.ImageField(label='Upload an image', required=False)
class Meta:
model = Advert
fields = (
'title', 'category', 'quantity', 'condition', 'price', 'description',
'image')
我以前从未使用过jQuery,那是创建流畅的下拉样式菜单的最佳选择吗?我必须做到这一点,以便他们不能选择父类别,而只能选择底部的子类别。
[定义功能update_form_field_choices
(例如在utils.py
中:]:
def update_form_field_choices(field, choices):
"""
Update both field.choices and field.widget.choices to the same value (list of choices).
"""
field.choices = choices
field.widget.choices = choices
然后,在__init__
中定义方法PostAdvertForm
:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
并且在此函数中,调用此函数,然后用返回正确选择的函数替换your_choices()
。记住选择格式(一个元组的元组)。
update_form_field_choices(field=self.fields['category'], choices=your_choices())
还请记住,ModelForm
为您定义了表单字段,因此您不必显式定义它们,除非您想更改默认定义中的内容。