2011-10-24 138 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 

真正的轻松,当你停止挖掘和质疑孔是否真的有必要。

相关问题