2011-10-24 68 views
1

我有一個具有ForeignKey的模型與另一個也具有ForeignKey的模型。我使用的是django表單嚮導(試圖支持儘可能早的django版本),它不是inlineformset友好的。我希望用戶在表單嚮導中添加模型和額外信息,並將其轉換爲正確的pk值(這樣,額外的信息可以依賴於組合)我想知道如何處理這個問題。帶有MultiValueField的FormWizard中的另一個ForeignKey的ForeignKey字段

爲了進一步澄清代碼。我有三個型號:

class Subject(models.Model): 
    title = models.CharField(...) 
    extra_info = models.CharField(...) 

class Topic(models.Model): 
    title = models.CharField(...) 
    extra_info = models.CharField(...) 
    subject = models.ForeignKey(Subject) 

class AwesomeThing(models.Model): 
    title = models.CharField(...) 
    topic = models.ForeignKey(Topic) 

現在,我想AwesomThing話題現場呈現給用戶在我的表單嚮導四個領域:

  • 主題
  • 主題額外信息
  • 主題
  • 主題額外信息

我使用的是MultiValueFieldMultiWidget做到這一點,但我不確定保留值和表單嚮導的步驟之間傳輸的最佳方式。我能夠做到這一點,但我擔心我的方法太頻繁地擊中數據庫。下面是我當前如何做到這一點:

class SubjectTopicField(MultiValueField): 
    widget = SubjectTopicInput # Multiwidget to present four input fields 
    hidden_widget = HiddenInput 

    def __init__(self, *args, **kwargs): 
    fields = (
     CharField(label='Subject'), 
     CharField(label='Subject extra information'), 
     CharField(label='Topics'), 
     CharField(label='Topic extra information'), 
     ) 

    super(SubjectTopicField, self).__init__(fields, *args, **kwargs) 

    def compress(self, data_list): 
    # If all four fields are present ... 
    if data_list and len(data_list) == 4: 
     # ... call and return the topic 'pk' value from a custom method that 
     # creates and/or gets the topic based on the subject and topic info 
     return get_or_create_topic(data_list[0], data_list[1], # Subject 
           data_list[2], data_list[3]) # Topic 

    return None 

我get_or_create_topic方法基本上只是查找主題和話題的這個組合是否存在,如果是的話返回它,如果不創建它。問題在於,這意味着它必須在每一步都擊中數據庫。我發現該字段的隱藏字段顯示只包含值列表(data_list),而不是該主題的pk值。我認爲這不是最佳的。有一個更好的方法嗎?我可能只是專注於使這個與MultiValueField一起工作,我沒有看到正確的方法來做到這一點。

+0

我想通了。由於我不能因信譽而自我回答我的帖子,因此我會等待幾個小時,然後再發布問題的答案。 –

回答

1

我想到了這一點,我認爲。答案是使用MultiWidget子類,但不能爲MultiValueField子類化。我只是將我的主題字段指向我的SubjectTopicInput,它繼承MultiWidget,然後除了解壓縮I子類value_from_datadict以返回pk(我知道我可以使它更漂亮,但這正是我所做的工作):

def value_from_datadict(self, data, files, name): 
    # Is there just a single value available which we can return? 
    single_value = data.get(name, None) 
    if single_value: return single_value 

    # No single value, let's try to find our topic (or create it) 
    super_value = super(SubjectTopicInput, self).value_from_datadict(data, files, name) 
    tc = get_or_create_topic(super_value[0], super_value[1], 
          super_value[2], super_value[3]) 

    if tc: return tc.pk 

    return None 

真正的輕鬆,當你停止挖掘和質疑孔是否真的有必要。

相關問題