2012-05-16 6 views
13

Есть ли способ не проходить в экземпляре модели для внешнего ключа при создании новой модели? Скажем, у меня есть следующие модели:Django ForeignKey Instance vs Raw ID

class Foo(models.Model): 
    description = models.CharField(max_length=100) 

    class Meta: 
     db_table = u'foo' 

class Bar(models.Model): 
    info = models.CharField(max_length=100) 
    foo = models.ForeignKey('Foo') 

    class Meta: 
     db_table = u'bar' 

Позднее запрос пост приходит к виду - я знаю, что идентификатор в Foo записи и просто хочу, чтобы вставить запись в таблицу бара.

если я:

new_bar = Bar(info="something important", foo=foo_id) 
new_bar.save() 

Я получаю поговорку «Невозможно присвоить "546456487466L ValueError": " Bar.foo" просто быть "экземпляр Foo"

Итак, я понимаю. .. он хочет, чтобы у меня был фактический экземпляр модели Foo.Я понимаю, что я могу просто получить Foo, а затем передать его. Но, похоже, должен быть способ переопределить эту функциональность. некоторые googling и чтение документов, а raw_id_fields в admin, по-видимому, является основной идеей (то есть, разрешить исходный идентификатор здесь). Но не вижу эту опцию в поле ForeignKey.

Кажется очень неэффективным, чтобы совершить кругосветное путешествие в базу данных, чтобы получить объект, чтобы получить идентификатор (который у меня уже есть). Я понимаю, что выполнение поездки в оба конца подтверждает, что идентификатор существует в базе данных. Но, эй ... вот почему я использую РСУБД и имею внешние ключи.

Благодаря

+0

Отличный, классический вопрос SO-ish. – trpt4him

ответ

20
new_bar = Bar(info="something important", foo_id=12345) 
new_bar.save() 

Вы также можете получить foreign key values directly. Некоторая оптимизация.

+0

Это сработало ... У меня все еще были проблемы, пока я не понял что-то. собираюсь добавить здесь 1 небольшую заметку и отредактировать ответ выше. В моем примере выше я фактически немного упростил. В моделях REAL «foo» первичный ключ таблицы не был «id». А иностранный не был «foo_id». Но вам нужно использовать имя поля + «_ id», чтобы заставить его работать. –

+1

Разве это не странно, что это не двойной знак подчеркивания, так как id - поле Foo. По крайней мере, вы используете двойное подчеркивание в запросах. – radtek

+0

@radtek, потому что вы не используете поле id Foo, вы используете поле foo_id в баре. Если вы используете какой-то клиент базы данных, вы увидите, что 'appname_foo' имеет столбец' id' и 'appname_bar' имеет столбец' foo_id'. Я имею в виду иначе, как бы вы знали, какой Foo идет в каждый бар? Поэтому в этом случае даже в запросах вы НЕ должны (и не должны) использовать двойной знак подчеркивания при работе с идентификатором (вы избегаете такого соединения). – semicolon