Сохранение модели с использованием PK связанного поля 2-го уровня в Django

#django #django-models

#django #django-модели

Вопрос:

У меня есть следующие модели:

 class A(models.Model):
    pass  # omitted for shortness

class B(models.Model):
    pass

class AB(models.Model):
    prop_a = models.ForeignKey('A')
    prop_b = models.ForeignKey('B')

class X(models.Model):
    prop_ab = models.ForeignKey('AB')
  

Я хочу сохранить модель экземпляра X , но без выполнения ab = AB.objects.get(prop_a=1, prop_b=2) and then x.prop_ab = ab .

Я хочу что-то вроде этого (при условии, что все правильные записи в A B и AB уже существуют):

 x = X()
x.prop_ab__prop_a__id = 1
x.prop_ab__prop_b__id = 2
x.save()
  

Возможно ли что-то подобное? (приведенный выше синтаксис не работает, я пробовал)

Комментарии:

1. Можете ли вы объяснить, чего вы пытаетесь достичь с помощью этого?

2. Мне нужно выполнить несколько save() X моделей в цикле foreach, поэтому мне также нужны get соответствующие AB записи в этом foreach. Я бы хотел свести к минимуму количество запросов, которые я выполняю, исключив get включение AB .

3. Afaik это невозможно, классу X требуется PK класса AB, поэтому вам нужно выполнить поиск запроса, чтобы определить этот PK. Но если вы уже знаете PK, то вы можете просто выполнить x.prop_ab_id = 1. Но вы должны учитывать, что оптимизация, которую вы пытаетесь достичь, может быть не очень полезной, поскольку действие вставки / обновления намного тяжелее, чем запрос выбора.

4. Вместо устранения get (который, вероятно, является самым быстрым возможным запросом), используйте bulk_create для оптимизации вставок.

5. @Peter это правда, но я также хочу свести к минимуму количество подключений (не обязательно процессорное время) к БД. Я буду использовать bulk_create , как предложил @Burhan Khalid, но я хочу сжать это настолько, насколько смогу. Вероятно, в конечном итоге я буду использовать сложный запрос для SELECT всех AB с одним запросом.

Ответ №1:

предполагая, что все правильные записи в A B и AB уже существуют

вы можете сделать это:

 x = X()
x.prop_ab.prop_a_id = 1
x.prop_ab.prop_b_id = 2
x.save()
  

Мне нужно выполнить несколько save() X моделей в цикле foreach, поэтому мне также нужно получить соответствующие AB записи в этом foreach. Я хотел бы свести к минимуму количество запросов, которые я выполняю get , путем устранения AB

 for x in X.objects.select_related('prop_ab'):
    x.prop_ab.prop_a_id = 1
    x.prop_ab.prop_b_id = 2
    x.save()