Django自定义模板中的ManyToManyField?

1 投票
1 回答
1495 浏览
提问于 2025-04-18 11:48

我正在尝试创建一个自定义对象添加模板。我已经完成了标题、描述等部分,但我搞不懂那个多对多字段的东西。

这是我的视图:

def add_product(request):
    form = ProductForm(request.POST or None)
    categories = Category.objects.all()
    if form.is_valid():
        product = form.save(commit=False)
        product.user = request.user

        at = slugify(form.cleaned_data['title'])
        if at in sluglist:
            n = 0
            while at in sluglist:
                n += 1
                at = slugify(form.cleaned_data['title'])+str(n)
            product.slug = at
            sluglist.append(product.slug)
            product.active = True
            product.save()
            return HttpResponseRedirect('/products/%s'%(product.slug))
        else:
            product.slug = slugify(form.cleaned_data['title'])
            sluglist.append(product.slug)
            product.active = True
            product.save()
            return HttpResponseRedirect('/products/%s'%(product.slug))


    return render_to_response("products/add.html", locals(), context_instance=RequestContext(request))

这是我的模型:

class Category(models.Model):
    title = models.CharField(max_length=120)
    description = models.CharField(max_length=500)
    slug = models.SlugField()
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)

    def __unicode__(self):
        return str(self.title)

    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"



class Product(models.Model):
    user = models.ForeignKey(User, null=True, blank=True)
    title = models.CharField(max_length=50)
    description = models.TextField(max_length=500)
    price = models.DecimalField(max_digits=20, decimal_places=2)
    categories = models.ManyToManyField(Category)
    slug = models.SlugField()
    order = models.IntegerField(default=0)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)
    active = models.BooleanField(default=True)

    def __unicode__(self):
        return str(self.title)

    class Meta:
        ordering = ['-order']

    def get_absolute_url(self, ):
        return reverse('single_product', args=[self.slug])

这是我的admin.py文件:

class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ('title',)}
    class Meta:
        model = Category

admin.site.register(Category, CategoryAdmin)




class ProductAdmin(admin.ModelAdmin):
    list_display = ('__unicode__','description','price','order','live_link')

    inlines = [TagInline, ProductImageInline]
    search_fields = ['title','description','price', 'tag__tag']
    list_filter = ['price', 'timestamp', 'updated']
    prepopulated_fields = {"slug": ('title',)}

    readonly_fields = ['live_link', 'timestamp', 'updated']

    class Meta:
        model = Product


    def live_link(self,obj):
        link = "<a href='/products/" + str(obj.slug)+ "/'>" + obj.title + "<a/>"
        return link

    live_link.allow_tags = True

admin.site.register(Product, ProductAdmin)

这是我的forms.py文件:

class ProductForm(ModelForm):
    categories = forms.ModelMultipleChoiceField
    class Meta:
        model = Product
        fields = ('title', 'description', 'price', 'categories')

这是我的add.html(添加东西的页面):

<form method='POST' action='' >
{% csrf_token %}
    <div class="form-group">
                <input type="text" placeholder="Başlık" class="form-control" name="title" value="" >
    </div>
    <div class="form-group">
                <textarea type="text" placeholder="Description" class="form-control" name="description" value="" ></textarea>
    </div>
    <div class="form-group">
                <input type="text" placeholder="Price" class="form-control" name="price" value="" >
    </div>

    <div class="form-group">
        <select multiple="multiple" name="categories" id="id_categories">
            {% for cat in categories %}
            <option>{{ cat }}</option>
            {% endfor %}
        </select>
    </div>
<input type='submit' value='Kaydet/Save' class="btn btn-info"/>

</form>

在forms.py和add.html中,如果不包含类别部分,它是可以正常工作的,但我想添加类别选择。当我在上面的代码中加入类别部分时,它就无法保存表单,也无法添加对象。我该如何解决这个问题呢?谢谢。

1 个回答

1

这个标签的值不是来自标签之间的内容(这些内容会填充菜单),而是来自标签本身的'value'属性。你需要把这一行:

<option>{{ cat }}</option>

改成这样:

<option value="{{cat.id}}">{{cat}}</option>

ModelChoiceField(用于ManyToMany对象的表单字段)期待的是一个模型的ID号(不过你也可以选择用其他模型字段,通过'to_field_name'属性)。如果选项标签中没有'value'属性,ModelChoiceField就无法接收到有效的值,这就是为什么模型无法保存的原因。

想了解更多信息,可以查看关于ModelChoiceFields的文档

撰写回答