Присвоение начальных значений поля в связанных административных формах Django
У меня есть довольно простое приложение Django (v1.3 в Red Hat), для которого я использую приложение администратора для создания и изменения записей базы данных. Одним из полей в моей базовой модели является поле даты. Каждый раз, когда соответствующее поле отображается в новой или редактируемой форме администратора, я бы хотел, чтобы начальным значением этого поля была сегодняшняя дата (и время). Пользователь может изменить его после этого, если он пожелает.
Я знаю, что могу установить значение поля по умолчанию в моем определении модели (то есть в models.py). Что хорошо работает, когда запись в базе данных создается впервые. Но для последующих вызовов изменения из формы вызов, который я назначил параметру по умолчанию (datetime.datetime.now), явно не вызывается.
Я посмотрел - и попробовал - довольно хорошо все многие предложенные решения, описанные в другом месте в stackru, но безуспешно. Большинство из них, кажется, вращаются вокруг вставки кода инициализации в подкласс ModelForm, например, что-то вроде этого...
class ConstantDefAdminForm(ModelForm) :
a_date_field = DateField(initial="datetime.datetime.now") # or now()
class Meta :
model = ConstantDef
widgets = {
...
}
или как то так...
class ConstantDefAdminForm(ModelForm) :
class Meta :
model = ConstantDef
widgets = {
...
}
def __init__(self, ...) :
# some initialisation of a_date_field
super(ConstantDefAdminForm, self).__init__(...)
Но ни один из этих подходов не работает. Начальное значение поля всегда равно значению, которое хранится в базе данных. Мое чтение документации Django состоит в том, что различные способы наложения начальных значений полей в формах работают только для несвязанных форм, а не для связанных форм. Правильно?
Но эта возможность (выборочно переопределять хранимые в данный момент значения) может показаться настолько популярным требованием, что я убежден, что должен быть способ сделать это.
Кому-нибудь там удалось это сделать?
Заранее спасибо,
Фил
5 ответов
Вот подход, который может работать. В классе администратора вашей модели измените значение obj.a_date_field
прежде чем форма будет связана. Значение по умолчанию для поля даты должно быть новым значением.
class MyModelAdmin(ModelAdmin):
...
def get_object(self, request, object_id):
obj = super(MyModelAdmin, self).get_object(request, object_id)
if obj is not None:
obj.a_date_field = datetime.now()
return obj
Обратите внимание, что get_object
не задокументировано, так что это немного хакерски.
В Джанго 1.4 default=<callable>
в декларации модели работает хорошо:
class MyModel(models.Model):
dt = models.TimeField(null=True, blank=True, default=datetime.datetime.now)
при каждом добавлении записи значение поля по умолчанию обновляется.
Но использование поля default
Этот параметр вызывает у меня некоторые проблемы с историей журнала администратора объектов DateField, которые каждый раз записываются как измененные, а также когда они не изменяются. Поэтому я принял решение, основанное на /questions/33402294/izmenit-model-administratora-po-umolchaniyu/33402312#33402312:
import datetime
class MyModelAdminForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(MyModelAdminForm, self).__init__(*args, **kwargs)
self.fields['dt'].initial = datetime.datetime.now
class MyModelAdmin(admin.ModelAdmin):
form = MyModelAdminForm
fields = ('dt',)
У меня была похожая проблема, и я нашел решение отсюда
Я думаю, что вы захотите сделать это:
class yourAdminModel(admin.ModelAdmin):
fields = ['your_date_field']
def add_view(self, request, form_url="", extra_context=None):
data = request.GET.copy()
data['your_date_field'] = datetime.date.today() # or whatever u need
request.GET = data
return super(yourAdminModel, self).add_view(request, form_url="", extra_context=extra_context)
Вы должны иметь возможность использовать auto_now с вашим полем DateTime, которое в соответствии с документами будет автоматически устанавливать значение now() при каждом сохранении формы
Начиная с Django 1.7 есть функция get_changeform_initial_data
в ModelAdmin, который устанавливает начальные значения формы:
def get_changeform_initial_data(self, request):
return {'dt': datetime.now()}