2011-01-12 20 views
6

Tengo el siguiente:hacer el usuario en un modelo predeterminado para el usuario actual

from django.contrib.auth.models import User 

class ClientDetails(models.Model): 
    created_by = models.ForeignKey(User) 
    ... 

¿Cómo hago created_by defecto al usuario actualmente conectado?

(quiero hacer esto por lo que puedo ocultarlo en la vista de administración, principalmente, sino también porque al guardar una instancia que no quiero estar llenando cada vez)

Respuesta

12

Ya que se necesita para obtener el usuario actualmente conectado desde un objeto request no se puede conseguir en save -method del modelo, pero se puede por ejemplo anular save_model -method el modelo de administrador:

class MyAdmin(admin.ModelAdmin): 
    def save_model(self, request, instance, form, change): 
     user = request.user 
     instance = form.save(commit=False) 
     if not change or not instance.created_by: 
      instance.created_by = user 
     instance.modified_by = user 
     instance.save() 
     form.save_m2m() 
     return instance 
+1

¿puedo dejar esto en una de mis vistas de administrador? (obviamente después de cambiar created_by y modified_by). ¿Alguna posibilidad de que puedas analizar esto por nosotros? – Sevenearths

+0

esta es la solución más útil, porque puedes usar "solicitud", no puedo creer que la haya perdido aquí http://django.me/save_model – tutuDajuju

1

ModelFields normales tienen una argumento predeterminado Pero ForeignKeys no sabe, por lo que supongo que debe trabajar con una señal post_save.

+0

+1, pero si fuera yo, simplemente anularé la función save() :) – mouad

+0

Entonces tendría que anular la función de guardado predeterminada del administrador ¿no? – Sevenearths

+0

Las versiones actuales de Django ciertamente permiten los valores predeterminados para claves externas. No estoy seguro de que alguna vez lo hayan hecho. Entonces, si alguien viene y lee esta respuesta hoy, en el mejor de los casos debería considerarse desactualizada. –

1

que encontré:

from django.db import models 
from django.contrib.auth.models import User 

class CurrentUserField(models.ForeignKey): 
    def __init__(self, **kwargs): 
     super(CurrentUserField, self).__init__(User, null=True, **kwargs) 

    def contribute_to_class(self, cls, name): 
     super(CurrentUserField, self).contribute_to_class(cls, name) 
     registry = registration.FieldRegistry() 
     registry.add_field(cls, self) 

class ClientDetails(models.Model): 
    created_by = CurrentUserField() 
... 

de here. ¿Pero no hay una manera más fácil?

+0

+ No sé cómo importar 'registration' – Sevenearths

+0

¡Debería leer el libro más, hay más que necesita, incluido el registro y un middleware! –

+0

probablemente sea el correcto – Sevenearths

6

que tenía un problema similar hace poco, esto es de mi archivo views.py

def CircleAdd(request): 

    form = CircleAddForm(request.POST) 

    if form.is_valid(): 

     Circle = form.save(commit=False) 
     Circle.Author = request.user 
     Circle = Circle.save() 

Y luego tuve un formulario para el modelo 'círculos', que era sólo un envoltorio realmente (forms.py)

class CircleAddForm(ModelForm): 
    class Meta: 
     model = Circle 

¡Recuerde importar el formulario en su punto de vista!

Editar: ni siquiera seguro si siquiera tiene que molestarse con forma separada, el paletón de la llave es el falso cometió, seguido por el verdadero

+0

no estoy seguro de lo que es forms.py (aún nuevo para django) I solo esperaba hacer esto en la interfaz de administración – Sevenearths

+0

Supongo que si puedo obtener el valor predeterminado en models.py, entonces también aparecerá el predeterminado en las vistas de administración y sitio – Sevenearths

+0

en los formularios y su respuesta ahora tiene sentido – Sevenearths

3

Sobre la base de la respuesta aceptada, si usted está mirando para hacer esto con vistas a la clase base, puede seguir las instrucciones en el docs, reemplazando el método form_valid() en la vista de clase:

# views.py 

from django.views.generic.edit import CreateView 

class CreateClient(CreateView): 
    def form_valid(self, form): 
     form.instance.created_by = self.request.user 
     return super(CreateClient, self).form_valid(form) 
+0

Tenga en cuenta que esto no funciona si el campo es obligatorio. – YPCrumble

4

tiene que reemplazar get_changeform_initial_data método en su clase de administración de modelo en el admin.py de la siguiente manera:

# admin.py 

class ClientDetailsAdmin(admin.ModelAdmin): 
    def get_changeform_initial_data(self, request): 
     get_data = super(ClientDetailsAdmin, self).get_changeform_initial_data(request) 
     get_data['created_by'] = request.user.pk 
     return get_data 

admin.site.register(ClientDetails, ClientDetailsAdmin) 

De esta forma se obtiene la solución más elegante ya que el campo created_by se archiva cuando se crea un nuevo registro.

Cuestiones relacionadas