Как получить доступ к request.user из чистого метода администратора ModelForm?

Я делаю кое-что на «чистке» в административной ModelForm:

class MyAdminForm(forms.ModelForm):
    def clean(self):
        # Some stuff happens...
        request.user.message_set.create(message="Some stuff happened")

class MyAdmin(admin.ModelAdmin):
    form = MyAdminForm

Помимо взлома threadlocals - как мне получить доступ к request.user, чтобы установить сообщение? Я не могу передать его конструктору формы, потому что он не вызывается из моего кода.


person Andy Baker    schedule 12.02.2010    source источник


Ответы (2)


Вы не можете сделать это в форме, не передав пользователя в конструктор формы. Вместо этого вы можете использовать функцию ModelAdmin.save_model, которая получает объект запроса.

Методу save_model присваивается HttpRequest, экземпляр модели, экземпляр ModelForm и логическое значение в зависимости от того, добавляется или изменяется объект. Здесь вы можете выполнять любые операции до или после сохранения.

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model

Изменить: поскольку вы хотите поместить логику/сообщения в чистую функцию, вы можете сделать что-то вроде:

class MyAdminForm(forms.ModelForm):
    user_messages = []
    def clean(self):
        # Some stuff happens...
        user_messages.append("Some stuff happened")

class MyAdmin(admin.ModelAdmin):
    form = MyAdminForm
    def save_model(self, request, obj, form, change):
        for message in form.user_messages:
            request.user.message_set.create(message=message)

Очень позднее редактирование:

user.message_set считается устаревшим в Django 1.4. Вместо этого вы должны использовать ModelAdmin.message_user. https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user

person Mark Lavin    schedule 12.02.2010
comment
Ммммм. Сообщение зависит от некоторой логики проверки, поэтому гораздо больше смысла жить в методе ModelForm clean(). Если я перенесу его в ModelAdmin save_model(), мне придется написать какую-то запутанную логику только ради отправки сообщения! - person Andy Baker; 12.02.2010
comment
Я переместил user_messages в инициализацию формы и добавил self. к строке «user_messages.append», и это сработало! Спасибо. - person Andy Baker; 12.02.2010
comment
Добавление user_messages в качестве переменной класса было для меня проблематичным, так как сообщения накапливались. Я решил это, добавив user_messages в get_form ModelAdmin def get_form(self, request, obj=None, **kwargs): form = super(ResortAdmin, self).get_form(request, obj, **kwargs) form.user_messages = [] return form И да, мне нужно было добавить self к вызову user_messages.append() - person Moritz; 17.07.2013
comment
О, и не забудьте позвонить super(MyAdmin, self).save_model(request, obj, form, change) - person Moritz; 17.07.2013

Вам нужно будет явно передать его туда в конструкторе, что обычно не делается.

Вы уверены, что хотите поместить этот материал в форму? Что именно вы хотели бы там делать? Разве недостаточно поднять ValidationError?

person gruszczy    schedule 12.02.2010
comment
Как уже упоминалось, конструктора нет в моем коде — он находится в contrib.admin. Сообщение, которое я хочу отправить, не является ошибкой. Это уведомление, когда сохранение формы затронуло другую часть системы. - person Andy Baker; 12.02.2010
comment
Но это странно - как вы можете быть уверены, что вы должны отправить сообщение до фактического сохранения объекта из формы? Между очисткой и сохранением может произойти много разных вещей. - person gruszczy; 12.02.2010
comment
Принимая во внимание, что мы говорим об изменении вида администратора, что может произойти между очисткой и сохранением? - person Andy Baker; 12.02.2010
comment
Другая очистка может вызвать ValidationError. - person gruszczy; 12.02.2010