[英]ForeignKey field with another ForeignKey in FormWizard with MultiValueField
我有一个带有ForeignKey的模型,而另一个模型也具有ForeignKey。 我正在使用不支持inlineformset的django表单向导(尝试尽可能支持旧的django版本)进行渲染 。 我希望用户在表单向导中同时放入模型和额外信息,并将其转换为正确的pk值(这样,额外信息就可以取决于组合),我想知道实现此目的的最佳方法。
用代码进一步阐明。 我有三种模式:
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的主题字段:
我正在将MultiValueField和MultiWidget一起使用来完成此操作,但是我不确定保留值并将其在表单向导中的各个步骤之间转移的最佳方法。 我能够做到这一点,但是我的方法恐怕太频繁地访问数据库了。 这是我目前的操作方式:
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一起使用 ,而我没有找到执行此操作的正确方法。
我想出了这一点。 答案是使用MultiWidget子类,而不是MultiValueField的子类。 我只是将主题字段指向继承MultiWidget的SubjectTopicInput ,然后除了解压缩我的子类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
当您停止挖掘并质疑孔是否真的必要时,这真的很容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.