Як я можу отримати всі RelatedManagers з певного примірника Django?

Скажімо, у мене є набір моделей Django:

class Article(models.Model):
    title = models.CharField(max_length=100, default='')
    content = models.TextField(default='', blank=False)
    created_at = models.DateTimeField(auto_now=True)
    creator = models.ForeignKey(User, null=True, blank=True)
    score = models.ForeignKey('Score', blank=True, null=True)
    points = models.ManyToManyField('Points')


class Score(models.Model):
    value = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True)
    creator = models.ForeignKey(User, null=True, blank=True)


class Points(models.Model):
    value = models.DecimalField(max_digits=3, decimal_places=1)
    caption = models.CharField(max_length=20, default='')
    created_at = models.DateTimeField(auto_now_add=True)
    creator = models.ForeignKey(User, blank=True, null=True)

І тепер я як-то отримую екземпляр моделі Score (не знаючи, що це модель Score ) та екземпляр моделі Points (знову , не знаючи, що це модель Points ):

>>> type(s)

>>> type(p)

Тепер я можу отримати доступ до набору відповідних примірників Article за допомогою такого коду:

>>> s.article_set

>>> p.article_set

Але це такий випадок, коли я знаю справжню схему БД, і я знаю, що атрибути називаються article_set . У моєму випадку я не знаю фактичної схеми БД. І я хочу отримати всі атрибути RelatedManager поточного екземпляра моделі.

Я думаю, що це можна реалізувати за допомогою атрибута ._meta </​​code>, але я не спромігся це зробити. Тому я, мабуть, потребую реального робочого прикладу, щось подібне до реалізації методу get_related_managers (self) .

1

1 Відповіді

Це, здається, працює для мене:

def get_related_managers(self):
    managers = []
    for related_object in self._meta.get_all_related_objects():
        managers.append(getattr(self, related_object.get_accessor_name()))
    return managers

Вам також доведеться спірити через self._meta.get_all_related_many_to_many_objects() , якщо ви хочете, щоб багато хто манішував.

4
додано
Без проблем. Сподівався, що це був кращий спосіб зробити це, оскільки недержавні атрибути (атрибути з провідним підкресленням, наприклад, _meta </​​code>) "не призначені для використання третіми сторонами; [і не гарантується] [d] що непублічні атрибути не зміняться або навіть не будуть вилучені ". (від python.org/dev/peps/pep-0008 ). Але я не бачив кращого способу зробити це.
додано Автор Will, джерело
Велике спасибі, я хоч я пропустив це, відкривши для себе властивість _meta </​​code>.
додано Автор ikostia, джерело
Власне, є багато речей, які ви не можете робити зі стандартним API Django, і які виконуються лише за допомогою атрибута _meta </​​code>. Іноді Джанго справді солодкий :)
додано Автор ikostia, джерело
ІТ КПІ - Python
ІТ КПІ - Python
625 учасників

Канал обговорень про всякі штуки зі світу пайтону. Прохання: 0. мати повагу одне до одного; 1. не матюкатися в сторону людей; 2. не захламляти тред повідомленнями по одному слову;