python - tutorial - Inline indirecto en Django admin
python manage.py startapp (3)
Tengo los siguientes modelos:
class UserProfile(models.Model):
user = models.OneToOneField(User)
class Property(models.Model):
user = models.ForeignKey(User)
Me gustaría crear un TabularInline
muestre cada Propiedad conectada a un TabularInline
particular en su página de administración de Django. El problema aquí es, por supuesto, que la propiedad no tiene una ForeignKey
directamente para UserProfile
, por lo que no puedo simplemente escribir
class PropertyTabularInline(admin.TabularInline):
model = Property
class UserProfileAdmin(admin.ModelAdmin):
inlines = (PropertyTabularInline,)
¿Cómo puedo hacer fácilmente lo que quiero?
Puede sobrescribir la página de administración de usuarios para mostrar tanto el Profile
como los modelos de Property
.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from myapp.models import *
class ProfileInline(admin.TabularInline):
model = Profile
class PropertyInline(admin.TabularInline):
model = Property
class UserAdmin(UserAdmin):
inlines = (ProfileInline, PropertyInline,)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
También puede eliminar cualquier propiedad de Usuario no deseada / no utilizada para que no se muestre (por ejemplo, Grupos o Permisos)
más aquí: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model
y aquí: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#a-full-example
Se puede lograr haciendo un cambio en sus modelos.
En lugar de crear una relación OneToOne de UserProfile
a User
, subclase User
creando UserProfile
. El código debería verse así:
class UserProfile(User):
# some other fields, no relation to User model
class Property(models.Model):
user = models.ForeignKey(User)
Eso resultará en la creación del modelo UserProfile
que ha ocultado la relación de OneToOne al modelo de User
, no duplicará el modelo de usuario.
Después de hacer ese cambio, su código funcionará. Hay algunos cambios bajo el capó, ya que UserProfile
ya no tiene su propia ID, puede acceder a los campos desde User
dentro de UserProfile
y es difícil intercambiar el modelo del User
usando la settings.AUTH_USER_MODEL
a mano) pero si esto no es un problema para usted, puede ser una buena solución.
class PropertyTabularInline(admin.TabularInline):
model = Property
def formfield_for_dbfield(self, field, **kwargs):
if field.name == ''user'':
# implement your method to get userprofile object from request here.
user_profile = self.get_object(kwargs[''request''], UserProfile)
kwargs["queryset"] = Property.objects.filter(user=user_profile)
return super(PropertyInLine, self).formfield_for_dbfield(field, **kwargs)
Una vez hecho esto, puede agregar esto en línea al usuario UserProfileAdmin como:
class UserProfileAdmin(admin.ModelAdmin):
inlines = (PropertyTabularInline,)
No lo he probado, pero eso debería funcionar.