tutorial theme template superusuario personalizar password crear django django-forms django-admin username

theme - Django: Cómo obtener el usuario actual en formularios de administrador



django-admin command (6)

Creo que encontré una solución que me funciona: para crear un ModelForm Django usa el formfield_for_db_field - formfield_for_db_field del administrador como una devolución de llamada.
Así que he sobrescrito este método en mi administrador y paso el objeto de usuario actual como un atributo con cada campo (que probablemente no sea el más eficiente, pero me parece más limpio que utilizar threadlocals:

def formfield_for_dbfield(self, db_field, **kwargs): field = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs) field.user = kwargs.get(''request'', None).user return field

Ahora puedo acceder al objeto de usuario actual en los formularios __init__ con algo como:

current_user=self.fields[''fieldname''].user

En ModelAdmin de Django, necesito mostrar formularios personalizados de acuerdo con los permisos que tiene un usuario. ¿Hay alguna manera de obtener el objeto de usuario actual en la clase de formulario, de modo que pueda personalizar el formulario en su método __init__ ?
Creo que guardar la solicitud actual en un hilo local sería una posibilidad, pero este sería mi último recurso, creo que estoy pensando que es un mal enfoque de diseño ....


Este caso de uso está documentado en ModelAdmin.get_form

[...] si quisiera ofrecer campos adicionales a los superusuarios, podría cambiar una forma de base diferente así:

class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): if request.user.is_superuser: kwargs[''form''] = MySuperuserForm return super().get_form(request, obj, **kwargs)

Si solo necesita guardar un campo, entonces podría anular ModelAdmin.save_model

from django.contrib import admin class ArticleAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): obj.user = request.user super().save_model(request, obj, form, change)


Esto es lo que hice recientemente para un Blog:

class BlogPostAdmin(admin.ModelAdmin): form = BlogPostForm def get_form(self, request, **kwargs): form = super(BlogPostAdmin, self).get_form(request, **kwargs) form.current_user = request.user return form

Ahora puedo acceder al usuario actual en mis forms.ModelForm accediendo a self.current_user

EDITAR: Esta es una respuesta antigua, y al mirarla recientemente, me di cuenta de que el método get_form debe enmendarse para que sea:

def get_form(self, request, *args, **kwargs): form = super(BlogPostAdmin, self).get_form(request, *args, **kwargs) form.current_user = request.user return form

(Tenga en cuenta la adición de *args )


La respuesta de Joshmaker no funciona para mí en Django 1.7. Esto es lo que tuve que hacer para Django 1.7:

class BlogPostAdmin(admin.ModelAdmin): form = BlogPostForm def get_form(self, request, obj=None, **kwargs): form = super(BlogPostAdmin, self).get_form(request, obj, **kwargs) form.current_user = request.user return form

Para obtener más detalles sobre este método, consulte esta documentación relevante de Django


Otra forma de resolver este problema es mediante el uso del currículo de Django, que es un poco más limpio que simplemente asociar el objeto de solicitud al modelo de formulario.

from django.utils.functional import curry class BlogPostAdmin(admin.ModelAdmin): form = BlogPostForm def get_form(self, request, **kwargs): form = super(BlogPostAdmin, self).get_form(request, **kwargs) return curry(form, current_user=request.user)

Esto tiene el beneficio adicional de hacer que su método init en su formulario sea un poco más claro, ya que otros comprenderán que se pasa como un kwarg y no solo como un atributo adjunto al objeto de clase antes de la inicialización.

class BlogPostForm(forms.ModelForm): def __init__(self, *args, **kwargs): self.current_user = kwargs.pop(''current_user'') super(BlogPostForm, self).__init__(*args, **kwargs)


tropecé con lo mismo y este fue el primer resultado de google en mi página. ¡Ayudó, buscó más Google y funcionó!

Así es como funciona para mí (django 1.7+):

class SomeAdmin(admin.ModelAdmin): # This is important to have because this provides the # "request" object to "clean" method def get_form(self, request, obj=None, **kwargs): form = super(SomeAdmin, self).get_form(request, obj=obj, **kwargs) form.request = request return form class SomeAdminForm(forms.ModelForm): class Meta(object): model = SomeModel fields = ["A", "B"] def clean(self): cleaned_data = super(SomeAdminForm, self).clean() logged_in_email = self.request.user.email #voila if logged_in_email in [''[email protected]'']: raise ValidationError("Please behave, you are not authorised.....Thank you!!") return cleaned_data