我正在学习如何在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>]
任何帮助/指向正确的方向都将受到赞赏。
答案 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