2012-08-03 76 views
1

我正在學習如何在python/django中編程,並且我向自己挑戰要爲打印業務構建一個電子商務網站。總體思路如下:如何在Django的DetailView中將ForeignKey顯示爲RadioSelect選項?

一旦客戶選擇了一個產品,他將不得不從一組選項(大小,幀,邊框寬度,材料),以定製自己的產品選擇。值得一提的是,每個選項都具有區別於其他特徵的特徵。例如:每個尺寸都有一個寬度和高度,這些屬性不是材料所必需的。然後他會上傳一張圖片(但我還沒有),商店將處理他的訂單。

因此,我選擇了設計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,這樣在用戶界面的每個選項顯示爲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>] 

任何幫助/針指向正確的方向將不勝感激。

+1

你似乎在談論,你認爲是不是一個形式,一種形式。 – slackjake 2012-08-03 04:28:55

+0

您可能還會發現,基於類的視圖是一個難以從Django開始的地方(特別是在處理表單時)。有關非基於類的介紹,請參閱Django的[「使用表單」](https://docs.djangoproject.com/en/1.4/topics/forms/)指南。 – supervacuo 2012-08-03 04:34:29

+0

@slackjake嗯......也許哈哈。我認爲我無法使用表單作爲產品視圖,因爲表單會將信息發佈到數據庫(即創建一個「新產品」)? – 2012-08-03 04:39:07

回答

2

簡而言之,DetailView用於顯示數據。既然你問了用戶提出的問題(「哪些材料?」,「哪個尺寸?」 ),你幾乎肯定會真的要使用的形式。這是什麼形式的設計!

爲了讓下面的工作,我建議你扭轉你的ForeignKey s的如何定義的;我假設你想要在多種產品中使用相同的材​​料,而不是相反的方式!像material = models.ForeignKey(Material, related_name='products')場從Material

添加到您的Product,並刪除product領域使用的形式可能會最終成爲你的情況很容易。退房"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插件 - 「創建從模型形式」載文(上圖)對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 
+0

感謝您的快速回答!我確實似乎有我的邏輯倒退^^)只是一個簡單的問題:該表單應該在「detail.html」模板中使用「post」方法嗎?或者,我將如何繼續,以便用戶不會在數據庫中創建新產品,而是將信息傳遞給購物車? (當然,添加東西到購物車是另一回事,但只是想確定我是否應該使用「發佈」?謝謝 – 2012-08-03 04:46:51

+1

爲此,您將需要將信息存儲在session/cookie中。您可能會使用CreateView但你需要覆蓋form_valid,不知道還有什麼其他的。 – slackjake 2012-08-03 05:05:07

+0

@slackjake謝謝!正如我所指出的,我仍然處於學習曲線中,你和@ supervacuo的回答都指向了正確的軌道,這真是太棒了!作爲一個在Stackoverflow中的新手,我不能高呼,但我的投票在spirt! – 2012-08-03 05:28:24

相關問題