2015-09-14 20 views
17

Ho i seguenti modelli:linea indiretta in Django Admin

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 

class Property(models.Model): 
    user = models.ForeignKey(User) 

vorrei creare un TabularInline visualizzando ogni proprietà collegato a una particolare UserProfile sulla sua pagina di amministrazione Django. Il problema qui è, naturalmente, che la struttura non dispone di un ForeignKey direttamente a UserProfile, quindi non posso scrivere semplicemente

class PropertyTabularInline(admin.TabularInline): 
    model = Property 

class UserProfileAdmin(admin.ModelAdmin): 
    inlines = (PropertyTabularInline,) 

Come posso facilmente fare quello che voglio?

risposta

1

È possibile sovrascrivere la pagina di amministrazione utente per visualizzare sia i modelli Profile sia i modelli 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) 

È possibile anche rimuovere qualsiasi proprietà utente indesiderato/inutilizzati venga visualizzato (ad esempio, gruppi o permessi)

più

qui: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model

e qui: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#a-full-example

+1

Questo non è quello che voglio, però - Voglio visualizzare il inline nella pagina di amministrazione del profilo, non nella pagina di amministrazione degli utenti. – haroba

0

è realizzabile apportando una modifica ai modelli.

Invece di creare rapporti OnetoOne da UserProfile a User, sottoclasse User creando UserProfile. Codice dovrebbe essere simile che:

class UserProfile(User): 
    # some other fields, no relation to User model 

class Property(models.Model): 
    user = models.ForeignKey(User) 

che si tradurrà nella creazione di UserProfile modello che hanno nascosto OnetoOne relazione al User modello, non duplicherà modello dell'utente.

Dopo aver apportato questa modifica, il codice funzionerà. Ci sono alcune modifiche sotto il cofano, come UserProfile non hanno più il proprio ID, è possibile accedere ai campi da User all'interno di UserProfile ed è difficile scambiare il modello User utilizzando settings.AUTH_USER_MODEL (che richiederà la creazione di alcune funzioni personalizzate restituendo il tipo corretto e cambiando la migrazione a mano) ma se questo non è un problema per te, potrebbe essere una buona soluzione.

+0

Questa non è un'alternativa. Il punto qui è che io * non * voglio che i campi dell'Utente siano accessibili su UserProfile poiché ho diversi modelli UserProfile-like con le relazioni OneToOne con Utente che hanno controlli di accesso diversi ecc. – haroba

1
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 volta fatto questo, è possibile aggiungere questa linea per utente UserProfileAdmin piace:

class UserProfileAdmin(admin.ModelAdmin): 
    inlines = (PropertyTabularInline,) 

non ho ancora testato, ma che dovrebbe funzionare.

+0

Questo non funzionerà con django 1.8 e forse anche 1.7, fallirà il controllo del sistema: ': (admin.E202) 'app.Property' non ha ForeignKey in 'app.UserProfile'. – GwynBleidD

+0

@GwynBleidD: working in django1.8 nella mia app –

+0

Tutte le operazioni che eseguono il controllo del sistema falliranno, ad esempio creando nuove migrazioni. – GwynBleidD