Как правильно использовать хелперы для расширения функциональности в моделях Django?

Я добавляю некоторые расширенные функции к моим моделям в Django. Чтобы не перегружать корневой интерфейс модели (и файл), я использую некоторые помощники как атрибуты модели.

Я хочу сгруппировать методы и свойства в эти помощники, и то, что я хочу, это что-то вроде:

class Product(models.Model):
    downloads = DownloadsHelper()
    # ....
    pass

p = Product.objects.first()
p.downloads.files_count(p)
p.downloads.reset_permissions(p)
# ...

Чтобы не передавать экземпляр помощнику каждый раз, я мог бы использовать другой подход.

class Product(models.Model):
    def __init__(self, *args, **kwargs):
        super(Product, self).__init__(*args, **kwargs)
        self.downloads = DownloadsHelper(self)
        self.shipping = ShippingHelper(self)

p = Product.objects.first()
p.downloads.files_count
p.downloads.reset_permissions()

И, наконец, более общий/концептуальный для python способ сделать все это был бы следующим:


class Helper:
    def __init__(self, helped):
        self.helped = helped

class Helper1(Helper):
    attribute_name = 'helloing'

    def hola(self): print("hola")


class Helper2(Helper):
    attribute_name = 'goodbying'

    def chau(self): print("chau")


class Helped:
    def __init__(self):
        self._install_helpers()

    def _install_helpers(self):
        for helper in self.helpers:
            setattr(self, helper.attribute_name, helper(self))

class MyHelped(Helped):
    helpers = [Helper1, Helper2]

h = MyHelped()
h.helloing.hola()
h.goodbying.chau()

И вопрос в следующем: Является ли этот последний подход правильным способом / хорошей практикой для того, чтобы сделать материал с точки зрения питонического ООП и "Djangoid". Есть ли в этом проблемы?

Спасибо, что прочитали!

Возможно, вы не показали всю сложность вашего метода, но из того, что вы показали, его можно немного упростить.

Вы можете использовать "прямое/простое" наследование, и если у вас много методов, то для организации вы можете префикснуть имена методов с h1_ и h2_, чтобы указать, из какого вспомогательного класса они взяты:

from django.db import models

class Helper1:
    def h1_hola(self):
        print("hola")

class Helper2:
    def h2_chau(self):
        print("chau")

class MyHelped(Helper1, Helper2, models.Model):
    pass

h = MyHelped()
h.h1_hola()
h.h2_chau()

Будет ли этот более простой подход достаточным для ваших конкретных нужд?

Вернуться на верх