如何在Django的Detail View中将外键显示为Radio Select选项?

时间:2012-08-03 04:13:23

标签: django e-commerce detailview

我正在学习如何在python / django中编程,我挑战自己为打印业务建立一个电子商务网站。一般的想法如下:

客户选择产品后,他必须从一组选项(尺寸,框架边框宽度,材料)中进行选择,以便自定义其产品。值得一提的是,每个选项都具有区别于其他选项的特征。例如:每个尺寸的宽度和高度都是材料不需要的属性。然后他将上传一张图片(但我还没有),商店将处理他的订单。

因此,我选择将models.py设计为如下(简化):

class Product(models.Model):
    title = models.CharField(max_length = 150)
    slug = models.SlugField(max_length = 150)
    base_price = models.DecimalField(max_digits = 12, decimal_places = 2, default=0.00)

    class Meta:
        verbose_name = ('Product')
        verbose_name_plural = ('Products')

    #Methods. There is a method for each option.
    def get_materials(self):
        materials = self.materials.all()
        return materials

#There is a model for each option. Each model has a ForeignKey to Product.
class Material(models.Model):
    product = models.ForeignKey(Product, verbose_name = "Product", related_name="materials")
    name = models.CharField(max_length = 150)
    code = models.SlugField(max_length=150)
    price_per_meter = models.DecimalField(max_digits = 12, decimal_places = 2, blank = True, default = 0.00)
    created_at = models.DateTimeField(auto_now_add = True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name_plural = "Materials"

为了简化我正在使用DetailView的事情。所以在我的catalogue.urls.py中:

from django.conf.urls import patterns, include, url
from django.views.generic import DetailView
from catalogue.models import Product

urlpatterns = patterns('',
    url(r'^(?P<pk>\d+)/$', DetailView.as_view(
        model = Product,
        template_name = "detail.html"
        )),
)

所以,这是最终

的问题

如何自定义DetailView,以便在UI中每个选项显示为RadioSelect?

已发布类似问题,但它们与表单更相关:即如何在表单中将ForeignKey显示为RadioSelect。

我目前的方法使用以下detail.html

{% extends "base.html" %}

{% block content %}

<h1>{{ product.title }}</h1>

<h2>Please select one of the following:</h2>
<p>{{ product.get_materials }}</p>
<p>{{ product.get_sizes }}</p>
<p>{{ product.get_border_width }}</p>
<p>{{ product.get_border_color }}</p>

{% endblock %}

呈现以下内容: 我在db

中添加了一些随机数据
Please select one of the following:

[<Material: Material 1>, <Material: Material 2>]

[<Size: Size 1>, <Size: Size 2>]

[<BorderWidth: Border 1>, <BorderWidth: Border 2>]

[<BorderColor: Color 1>, <BorderColor: Color 1>]

任何帮助/指向正确的方向都将受到赞赏。

1 个答案:

答案 0 :(得分:2)

简而言之,DetailView用于显示数据。鉴于您要问用户问题(“哪些材料?”,“哪些尺寸?”),您几乎肯定会想要使用表格。这就是为什么形式设计的!

为了使以下工作正常,我建议您改变ForeignKey的定义方式;我假设你想要在多种产品中使用相同的材​​料,而不是相反的方式!在material = models.ForeignKey(Material, related_name='products')添加Product之类的字段,然后从product 等删除Material字段。

在您的情况下,使用表单可能会非常容易。查看"Creating forms from models" documentation,然后尝试以下内容:

# urls.py
from django.views.generic import CreateView

urlpatterns = patterns('', ...
    url(r'^(?P<pk>\d+)/$', CreateView.as_view(
        model = Product,
        template_name = "add_product.html"
    )),
)

这将为您提供默认的Select小部件 - “从模型创建表单”documentaiton(上图)中包含有关customising the widget used to draw form fields的信息。您需要创建一个新表单(继承自ModelForm)并将该视图指向该表单:

# forms.py
from django import forms

from catalogue.models import Product

class ProductForm(forms.ModelForms):
    class Meta:
        model = Product 
        widgets = {
            'material': forms.RadioSelect()
            ...
        }

# urls.py

from catalogue.forms import ProductForm

# add the following parameter to your call to as_view():
...
    'form_class': ProductForm