Как правильно использовать хелперы для расширения функциональности в моделях 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()
Будет ли этот более простой подход достаточным для ваших конкретных нужд?