Поле ForeignKey с другим ForeignKey в FormWizard с MultiValueField

У меня есть модель с ForeignKey для другой модели, у которой также есть ForeignKey. Я визуализирую его с помощью мастера форм django (пытаясь поддерживать как можно более старую версию django), который не дружественный к inlineformset. Я хочу, чтобы пользователь поместил обе модели и дополнительную информацию в мастер форм и перевел ее в правильное значение 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)

Теперь я хочу представить поле 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, но я не вижу правильного способа сделать это.


person Tryggvi B    schedule 24.10.2011    source источник
comment
Я понял это. Поскольку я не могу самостоятельно ответить на свой пост из-за репутации, я подожду несколько часов, прежде чем опубликую ответ на свой вопрос.   -  person Tryggvi B    schedule 24.10.2011


Ответы (1)


Я понял это, я думаю. Ответ состоял в том, чтобы использовать подкласс MultiWidget, но не подкласс MultiValueField. Я просто указываю свое поле тем на мой SubjectTopicInput, который наследует MultiWidget, а затем в дополнение к распаковке я создаю подкласс 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

Очень легко, когда вы перестаете копать и задаетесь вопросом, действительно ли нужна яма.

person Tryggvi B    schedule 25.10.2011