1

私は、ForeignKey を持つ別のモデルへの ForeignKey を持つモデルを持っています。inlineformset フレンドリーではない django フォーム ウィザード (可能な限り古いバージョンの django をサポートしようとしている) でレンダリングしています。ユーザーがモデルと追加情報の両方をフォーム ウィザードに入力し、それを正しい pk 値に変換してもらいたい (追加情報が組み合わせに依存するようにする) これにアプローチする最善の方法について疑問に思っています。

コードでさらに明確にする。私は3つのモデルを持っています:

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のトピックフィールドを4 つのフィールドとしてユーザーに提示したいと考えています。

  • 主題
  • 件名追加情報
  • トピック
  • トピックの追加情報

これを達成するために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 メソッドは基本的に、件名とトピックのこの組み合わせが存在するかどうかを調べ、存在する場合はそれを返し、存在しない場合は作成します。問題は、これがすべてのステップでデータベースにアクセスする必要があることです。このフィールドの隠しフィールド プレゼンテーションは、トピックの pk 値ではなく、値のリスト (data_list) を保持しているだけであることがわかります。私の意見では、それは最適ではありません。これを行うより良い方法はありますか?これをMultiValueFieldで機能させることに集中するだけかもしれませんが、これを行う適切な方法がわかりません。

4

1 に答える 1

1

私はこれを考え出したと思います。その答えは、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

掘るのをやめて、その穴が本当に必要かどうかを考えると、本当に簡単です。

于 2011-10-25T08:51:37.073 に答える