1

我正在学习如何在 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 %}

这呈现以下内容: 我向数据库添加了一些随机数据

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>]

任何正确方向的帮助/指出将不胜感激。

4

1 回答 1

2

简而言之,aDetailView用于显示数据。鉴于您正在向用户提出问题(“哪种材料?”、“哪种尺寸?”),您几乎肯定会真的使用表格。这就是表单的设计目的!

为了使以下工作,我建议您颠倒ForeignKeys 的定义方式;我假设您希望在多种产品中使用相同的材​​料,而不是相反!material = models.ForeignKey(Material, related_name='products')向您的中添加一个字段Product,并从中删除该product字段Material 等。

在您的情况下,使用表单可能会非常容易。查看“从模型创建表单”文档,并尝试以下操作:

# 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小部件 - “从模型创建表单”文档(上)包含有关自定义用于绘制表单字段的小部件的信息。您需要创建一个新表单(继承自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
于 2012-08-03T04:32:54.087 回答