Django: набор внешних ключей не найден после сохранения объекта - PullRequest
2 голосов
/ 07 февраля 2011

У меня есть модель вопроса и модель выбора mcq с внешним ключом к вопросу.

class Question(models.Model):
    statement = models.TextField(max_length=1024)
    def save(self, *args, **kwargs):
        super(Question,self).save(*args,**kwargs)
        #ques = Question.objects.get(id = self.id)
        f = open('/tmp/prj/log.txt', 'w')
        choiceobjs = self.choice_set.all()
        if choiceobjs:
           f.write("choices found")
        else:
           f.write("choices not found.. zilch")
        f.close()

 class Choice(models.Model):
    value = models.TextField(max_length=1024)
    question = models.ForeignKey(Question)

Теперь я переопределил метод сохранения вопроса.Даже после того, как вопрос был сохранен, я не могу найти choice_set в методе сохранения!Я всегда получаю "выбор не найден .. пшик" в моем лог-файле.

ОБНОВЛЕНИЕ: я создаю свой вопрос в интерфейсе администратора, и объекты 'Выбор' создаются 'встроенными'.

Таким образом, измененный вопрос таков: в какой последовательности создаются «встроенные» поля / модели и основная модель?Как я могу отложить проверку наличия внешнего ключа в методе сохранения, чтобы «иностранный ключ» стал видимым?

1 Ответ

3 голосов
/ 07 февраля 2011
class Foo(models.Model):
    pass


class Bar(models.Model):
    foo = models.ForeignKey(Foo)

При использовании встроенных символов Bar в администраторе Foo Django должен сначала сохранить объект Foo, поскольку объектам Bar требуется первичный ключ для ссылки на него в ForeignKey:

self.save_model(request, new_object, form, change=False)
form.save_m2m()
for formset in formsets:
    self.save_formset(request, form, formset, change=False)

http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L870

Это означает, что при вызове метода Foo save встроенные объекты Bar еще не сохранены и поэтому не могут быть запрошены. Поэтому вам нужно обойти эту проблему, если вам нужно получить доступ к этим объектам, когда экземпляр Foo был сохранен в админке (с использованием строк Bar).

Одним из возможных решений было бы присоединение к сигналу post_save Bar, посмотреть, на какой объект Foo он ссылается, и выполнить соответствующий код. Но это сработает при каждом изменении, даже если объект Foo не был создан.

...