Manajer kustom tunggal untuk Beberapa model di Django

Saya memiliki beberapa model yang terhubung satu sama lain dengan hubungan ForeignKeys.
Yang utama dalam hierarki semacam ini berisi bidang pemilik.

Saya ingin membuat satu pengelola khusus untuk semua model ini yang mengubah kumpulan kueri yang dikembalikan bergantung pada model yang memanggilnya.

Saya tahu bahwa manajer dapat mengakses self.model untuk mendapatkan model yang dilampirkannya.

Class Main(models.Model)
  owner=models.ForeignKey (User)
  owned = OwnedManager()

Class Second(models.Model)
  main=models.ForeignKey('Main')
  owned = OwnedManager()

Class Third(models.Model)
  second=models.ForeignKey('Second')
  owned = OwnedManager()

Saya ingin Manajer Kustom saya memiliki perilaku seperti ini:

class OwnedManager(models.Manager): 
    def get_owned_objs(self, owner):
        if self.model == 'Main': # WRONG: How do I get the model name?
            owned_main = self.filter(owner=owner)
            return owned_main
        elif self.model == 'Second':
            owned_second = self.filter(main__owner=owner)
            return owned_second
        else:
            owned_third = self.filter(second__main__owner=owner)
            return owned_third

Agar memiliki cara yang konsisten untuk menyebutnya di berbagai model, seperti:

main_object.owned.get_owned_objs(owner=user1) # of the Model Main
second_object.owned.get_owned_objs(owner=user1) # of the Model Second
third_object.owned.get_owned_objs(owner=user1) # of the Model Third

PERTANYAAN:

  • self.model == 'Main' salah. Saya tidak mendapatkan nama model seperti ini. Apakah ada cara untuk mendapatkannya?
  • Apakah ini efisien? Apakah Anda tahu cara yang lebih baik untuk menerapkan ini? Mungkin Warisan Manajer Kustom?

EDIT - SOLUSI SAYA: Jawaban yang diterima di bawah ini adalah solusi yang bagus tetapi saya juga menemukan cara untuk mendapatkan nama model dari model tertentu yang memanggil manajer khusus, yaitu:

if self.model.__name__ == 'Main':

Kuncinya di sini adalah atribut __name__


person Leonardo    schedule 31.07.2013    source sumber


Jawaban (1)


1) Membuat model abstrak

class AbstractModel(models.Model):
    class Meta(models.Meta):
        abstract = True

    objects = OwnedManager()

2) Mewarisi model Anda dari AbstrakModel, masukkan beberapa kunci di meta

class Model(AbstractModel)
    class Meta(AbstractModel.Meta):
        filter_key = 'some_key'

3) Desain ulang OwnedManager Anda

class OwnedManager(models.Manager): 
    def get_owned_objs(self, owner):
        if hasattr(self.model._meta, 'filter_key'):
            return self.filter(**{self.model._meta.filter_key: owner})

Sekarang Anda dapat menggunakan SomeModel.objects.get_owned_objs(owner=user1) di model warisan mana pun, di mana filter_key disetel tanpa mendapatkan nama model.

person Andrey Nelubin    schedule 31.07.2013
comment
Terima kasih, sepertinya solusi yang bagus, saya akan mencobanya. Saya juga menemukan cara untuk mendapatkan nama model dari manajer khusus. Saya telah memperbarui pertanyaan saya termasuk juga solusi saya. - person Leonardo; 02.08.2013