Django фильтрация: экземпляр модели против модели ПК - PullRequest
3 голосов
/ 23 января 2020

Я наткнулся (по крайней мере для меня) на довольно странное поведение в Django. Я не уверен, поддерживается ли это / разрешено ли поведение.

Предположим, у меня есть следующая модель:

class Club
    name = CharField(....)
    memberships = models.ManyToManyField(Person, through=ClubMembership, related_name='clubs')

    def getMembership(self, personID):
        return ClubMembership.objects.get(club_id=self.id, person_id=personID)

Очевидно, getMembership возвращает связанный экземпляр ClubMembership (Пока давайте предположим, что мы вызываем этот метод только для лиц, которые на самом деле находятся в клубе).

Теперь, при вызове этого метода, я обнаружил, что:

club = Club.objects.get(...)
person = Person.objects.get(...)

membership = club.getMembership(person)

и

club = Club.objects.get(...)
person = Person.objects.get(...)

membership = club.getMembership(person.id)

дают правильное членство. Есть ли какие-нибудь маги c, происходящие внутри методов filter / get, которые проверяют, является ли ключевое слово passend (для person_id) на самом деле целым числом (pk) или экземпляром модели?

Если оба действительны и разрешены, каковы последствия? Есть ли разница в производительности? Какой метод предпочтительнее?

Из c Я мог бы фильтровать по всей модели человека, а не только по идентификатору, например, так:

def getMembership(self, person):
        return ClubMembership.objects.get(club_id=self.id, person=person)

Но на самом деле, это было бы намного медленнее, верно?

1 Ответ

3 голосов
/ 23 января 2020

Как указано в Запросы к связанным объектам В разделе документации нет разницы между целым числом (pk) или экземпляром модели.

В их примере, если у вас есть объект Blog b при id = 5 следующие три запроса будут идентичны:

Entry.objects.filter(blog=b) # Query using object instance
Entry.objects.filter(blog=b.id) # Query using id from instance
Entry.objects.filter(blog=5) # Query using id directly
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...