#python #django #object #initialization
#python #django #объект #инициализация
Вопрос:
Я новичок в Python и Django, но чувствую, что должен быть более аккуратный способ сделать это, чем я нашел.
У меня есть модель Django, которая имеет атрибут date с нетривиальным значением по умолчанию, что означает, что мне нужно немного логики для его настройки. Я пробовал несколько способов сделать это, но, к сожалению, это единственный, который пока работал для меня ( models.py
внутри weeks
приложения):
def first_day_of_next_week():
return timezone.now().date() - datetime.timedelta(days=timezone.now().date().weekday()
datetime.timedelta(days=7)
class Week(models.model):
start_of_week = models.Datefield('Date of the first day of the week',
unique=True, default=first_day_of_next_week())
Мне очень не нравится, когда функция плавает за пределами любого подобного класса (но у меня нет опыта, чтобы знать, действительно ли это плохо). Я пытался включить его в статический или классовый метод или в __init__
процесс в течение недели, но не могу заставить ни один из этих подходов работать должным образом (в частности, Django, похоже, усложняет перехват __init__
).
Теперь, когда у меня работает модель Week , я хочу создать экземпляр weeks с Week.objects.get_or_create()
помощью from views.py
, но здесь я столкнулся с проблемой , что мне нужна та же first_day_of_next_week()
логика, чтобы быть доступным внутри views.py
. (Это то, что подтолкнуло меня к попытке перенести логику на статический или классовый метод, к которому можно было бы получить доступ views.py
.) Я могу копировать first_day_of_next_week()
и вставлять views.py
, и это работает, но это кажется неправильным по разным причинам. Я полагаю, что я мог бы не использовать значение по умолчанию и сохранить логику для создания только недели views.py
, но у меня сложилось впечатление, что предпочтительнее иметь всю логику, связанную с неделей, в модели, где это возможно.
Что бы сделал опытный программист на Python?
Комментарии:
1. «Мне очень не нравится, когда функция плавает за пределами любого подобного класса (но у меня нет опыта, чтобы знать, действительно ли это плохо). » Это неплохо. Это совершенно нормально. Функции, которые не требуют доступа к внутреннему состоянию класса, не должны быть членами класса
2. Я ответил на вопрос в названии поста, но на самом деле ваш вопрос не об этом, а об архитектуре. Чтобы понять, как организовать ваш код, вам нужно узнать, что такое уровни архитектуры и как организовать ваш код в слоях. Я могу только порекомендовать прочитать несколько книг. Есть один, который мне нравится github.com/cosmicpython/book .
3. Спасибо @juanpa.arrivillaga, это полезный указатель, но разве не все статические методы соответствуют этому критерию?
4. @Dan да, я бы согласился,
staticmethod
это довольно бессмысленно, и почти всегда было бы лучше как функция уровня модуля. Иногда они хороши как инструмент для организации кода / проектирования API…. Но в большую часть кода, который я написал на Python за последние 4 года профессионально, я включил, возможно, один или два staticmethod
Ответ №1:
Модели Django по-прежнему являются классами python. Вы можете использовать __init__
для инициализации, как это было задумано python:
def first_day_of_next_week():
return timezone.now().date() - datetime.timedelta(
days=timezone.now().date().weekday() datetime.timedelta(days=7)
)
class Week(models.model):
start_of_week = models.DateField(
'Date of the first day of the week', unique=True
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.start_of_week = self.start_of_week or first_day_of_next_week()
Я также рекомендую делать это вместо использования auto_now
ключевых слов или auto_now_add
DateField, DateTimeField, поскольку в противном случае вы не сможете передавать свои собственные значения в эти поля в тестах, django переопределит ваши значения во время сохранения в БД.