Django prefetch_related на неявна релация

Да кажем, че правя приложение за адресна книга.

class AddressBookEntry(models.Model):
    address_book = models.ForeignKey(AddressBook)
    name = models.CharField()
    email = models.EmailField()

class User(models.Model):
    name = models.CharField()
    email = models.EmailField()

И двата обекта имат поле за имейл. Сега искам да намеря всички адресни книги, в които се появява даден потребител. Затова правя метод на User like

    def entries(self):
        return AddressBookEntry.objects.filter(email=self.email)

Това работи добре, но когато извличам няколко потребители, трябва да изпълня DB заявка веднъж на потребител. Бих искал да направя User.objects.all().prefetch_related('entries'), но това не работи, тъй като entries е метод, а не ForeignKey.

So-

  • има ли начин по някакъв начин да кажа на django, че тук има връзка, без изрично да има поле много към много с неговата таблица чрез, така че да мога да използвам select_related?
  • или има ли начин да направя JOIN между обектите, когато извличам потребителите (това би било кръстосано свързване според мен, но би било по-добре от това, което имам сега.)

person joerick    schedule 11.04.2014    source източник
comment
Това наследена база данни ли е, която не можете да промените? Ако не, защо вместо това просто не направите полето email в AddressBookEntry M2M връзка с User?   -  person Selcuk    schedule 11.04.2014
comment
Имейлът в AddressBookEntry се въвежда от потребителя, той може да въвежда имейл адреси на хора, които не са потребители на приложението.   -  person joerick    schedule 11.04.2014
comment
Моля, добавете дефиницията на модела AddressBookEntries към публикацията си. Защо имате и модел AddressBookEntries, и модел AddressBookEntry? Това изглежда странно.   -  person garbanzio    schedule 20.12.2014
comment
@garbanzio съжалявам, това беше печатна грешка. Коригирах публикацията.   -  person joerick    schedule 20.12.2014


Отговори (1)


По-"Django" начинът да го направите би бил да имате изрично поле за връзка:

class AddressBookEntry(models.Model):
    address_book = models.ForeignKey(AddressBook)
    name = models.CharField()
    user = models.ForeignKey("User", related_name="entries")

class User(models.Model):
    name = models.CharField()
    email = models.EmailField()

User.objects.all().select_related('entries')
person Anentropic    schedule 20.12.2014