Django сокращает запрос на сохранение в ForeignKeyField - PullRequest
0 голосов
/ 02 июля 2019

У меня есть 2 модели Owners, Relationships

Владельцы

class Owner(models.Model):
    id = models.BigAutoField(primary_key=True)
    nickname = models.CharField(max_length=20, unique=True)

Отношения

class Relationships(models.Model):
    id = models.BigAutoField(primary_key=True)
    owner = models.ForeignKey(Owner, on_delete=models.CASCADE, related_name='relationship_owner')
    target_owner = models.ForeignKey(Owner, on_delete=models.CASCADE, related_name='relationship_target_owner')

Чтобы добавить строки к Relationships, я использовал запрос ниже.

owner1 = Owner.objects.filter(nickname='hide').first()
owner2 = Owner.objects.filter(nickname='john').first()
Relationships.objects.create(owner=owner1, target_owner=owner2)

Это довольно ясно.Но когда я проверяю django-debug-toolbar, он обращается к базе данных 3 раза.

  1. Получить nickname=hide из таблицы владельцев.

  2. Получить nickname=john из таблицы владельцев.

  3. Вставить в hide и john в таблицу отношений.

Интересно, этообщий способ?

Или, есть ли какой-либо четкий способ выполнения вышеуказанного запроса?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 02 июля 2019

Попробуйте с подзапросами :

from django.db.models import Subquery

owner1 = Owner.objects.get(nickname='hide')
owner2 = Owner.objects.get(nickname='john')

Relationships.objects.create(
    owner=Subquery(owner1)),
    target_owner=Subquery(owner2)
)
0 голосов
/ 02 июля 2019

Если вы преобразуете поле nickname в первичный ключ Owner, или , который вы используете to_field, то вы можете использовать его какэто:

<i># If you are using <b>to_field</b></i>
class Relationships(models.Model):
    id = models.BigAutoField(primary_key=True)
    owner = models.ForeignKey(Owner, on_delete=models.CASCADE, related_name='relationship_owner',<b>to_field='nickname'</b>)
    target_owner = models.ForeignKey(Owner, on_delete=models.CASCADE, related_name='relationship_target_owner', <b>to_field='nickname'</b>)

<i># usage</i>
Relationships.objects.create(<b>owner_id</b>='nick', <b>target_owner_id</b>='john')
0 голосов
/ 02 июля 2019

Поскольку у вас есть ForeignKey отношение к этой модели, вы можете использовать следующий метод:

owner = Owner.objects.filter(nickname='hide').first()
owner2 = Owner.objects.filter(nickname='john').first()
owner.relationships_set.create(target_owner=owner2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...