Структурирование Django-App для присоединения пользовательских бизнес-правил к экземплярам объектов - PullRequest
0 голосов
/ 22 ноября 2010

Я разорван, как структурировать мой код, чтобы он соответствовал бизнес-правилам, специфичным для экземпляров конкретной модели.

Например.Допустим, у меня есть модель Contact с полем типа и choices=(('I','Individual'),('C','Company)).В зависимости от типа модели, которая у меня есть, я мог бы захотеть использовать собственные методы.

Так что подумать вслух, что-то вроде этого было бы неплохо:

class IndividualContact(Contact):
""" A custom class used for Contact instances with type='I' """
    criteria = Q(type='I')

# The goal here is that Contact is now aware of IndividualContact and constructs
# objects accordingly.
Contact.register(IndividualContact)

Или даже:

class SpecialContact(Contact):
""" A custom class used for the contact with pk=1 """
    criteria = Q(pk=1)

В этот момент у меня есть хороший дом для моего специального кода, специфичного для экземпляра.

Одна из альтернатив, которые я исследовал, - это использование наследования моделей и избегание таких вещей, как поля типов, которые придают новое поведение.Таким образом, новые классы элегантно подключаются к существующей платформе, и вы прекрасно настроены для добавления настраиваемых полей к вашим различным типам на случай, если они вам понадобятся.

В моем случае у меня есть система кредитования ресурсов на сайтеэто позволяет мне говорить такие вещи, как «У вас может быть только 2 объявления и 20 фотографий».Отдельные типы ресурсов нормированы, но есть общая таблица кредитов, которая дает вам кредиты для различных типов контента.Логика подсчета ваших списков и фотографий варьируется в зависимости от типа объекта, с которым вы работаете.

IE:

listing_credit = Credit.objects.create(content_type=ContentType.objects.get_for_model(Listing), user=user, credit_amt=2)

# Should subtract **active** listings from current sum total of Listing credits.
listing_credit.credits_remaining()

photo_credit = Credit.objects.create(content_type=ContentType.objects.get_for_model(Photo), user=user, credit_amt=5)

# Photos have no concept of an active status, so we just subtract all photos from the current sum total of Listing credits. 
# Also, the Photo might be associated to it's user through a 'created_by' field whereas
# Listing has a user field.  
photo_credit.credits_remaining()

Мой текущий подход - это отдельные классы, но яЯ хотел бы уменьшить этот шаблон и необходимость создания N отдельных таблиц только с credit_ptr_id.

1 Ответ

1 голос
/ 22 ноября 2010

Посмотрите на прокси-модели Django.Они позволяют вам делать именно то, что вы хотите.

http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models

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

...