2015-09-14 19 views
17

mam następujące modele:Pośrednie inline w Django administratora

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

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

Chciałbym stworzyć TabularInline wyświetlając każdy obiekt podłączony do konkretnego UserProfile na swojej stronie administratora Django. Problemem tutaj jest, oczywiście, że nieruchomości nie posiada ForeignKey bezpośrednio do UserProfile, więc nie można po prostu napisać

class PropertyTabularInline(admin.TabularInline): 
    model = Property 

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

Jak można łatwo zrobić to, co chcę?

Odpowiedz

1

Można zastąpić stronę administratora użytkownika, aby wyświetlić modele Profile i 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) 

Można również usunąć wszelkie niechciane/nieużywane właściwości użytkownika od wyświetlane są (na przykład grupy lub uprawnienia)

więcej tutaj: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model

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

+1

To nie jest to, czego chcę - chcę wyświetlać wstawiane na stronie administratora profilu, a nie na stronie administratora użytkownika. – haroba

0

Jest to osiągalne dokonując jednej zmiany w swoich modelach.

Zamiast tworzenia relacji OneToOne z UserProfile do User, podklasę User tworzenia UserProfile. Kod powinien wyglądać tak:

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

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

To spowoduje utworzenie UserProfile modelu, które zostały ukryte OneToOne relacji do User modelu, to nie będzie powielać modelu użytkownika.

Po wykonaniu tej zmiany Twój kod będzie działał. Pod maską wprowadzono kilka zmian, takich jak UserProfile, które nie mają już własnego identyfikatora, można uzyskać dostęp do pól od User wewnątrz UserProfile i ciężko jest zamienić model User przy użyciu settings.AUTH_USER_MODEL (to będzie wymagało utworzenia niestandardowej funkcji zwracającej odpowiedni typ i zmieniającej migrację ręcznie;), ale jeśli nie stanowi to dla ciebie problemu, może być dobrym rozwiązaniem.

+0

To nie jest alternatywa. Chodzi mi o to, że nie * chcę * aby pola z User były dostępne w UserProfile, ponieważ mam kilka modeli podobnych do UserProfile z OneToOne relacjami z użytkownikiem, które mają różne kontrole dostępu itp. – 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) 

kiedy już to zrobi, można dodać ten inline użytkownikowi UserProfileAdmin lubię:

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

jej nie testowane, ale to powinno działać.

+0

To nie zadziała dla django 1.8 i może 1.7 również, to się nie powiedzie w trakcie sprawdzania systemu: ': (admin.E202) 'app.Property' nie ma klucza obcego do 'app.UserProfile''. – GwynBleidD

+0

@GwynBleidD: working in django1.8 w mojej aplikacji –

+0

Wszystkie operacje, które wykonują sprawdzenie systemu, zawiodą, na przykład tworząc nowe migracje. – GwynBleidD

Powiązane problemy