Присвоение начальных значений поля в связанных административных формах 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()}
Другие вопросы по тегам