2011-10-27 12 views
13

Czy istnieje sposób na zrobienie modelu tylko do odczytu w administratorze django? ale mam na myśli cały model. Więc, bez dodawania, bez usuwania, bez zmiany, po prostu zobaczyć obiekty i pola, wszystko jako tylko do odczytu?Cały model jako tylko do odczytu

+1

Jest to praca w toku: https: // github.com/django/django/pull/5297 – Bosco

Odpowiedz

11

ModelAdmin zapewnia get_readonly_fields hak() - Poniżej znajduje niesprawdzone, mój pomysł jest do określenia wszystkich dziedzinach drogę ModelAdmin robi, bez uruchamiania w rekursji z tylko do odczytu pola sami:

from django.contrib.admin.util import flatten_fieldsets 

class ReadOnlyAdmin(ModelAdmin): 
    def get_readonly_fields(self, request, obj=None): 
     if self.declared_fieldsets: 
      fields = flatten_fieldsets(self.declared_fieldsets) 
     else: 
      form = self.get_formset(request, obj).form 
      fields = form.base_fields.keys() 
     return fields 

następnie podklasę/mixin tego administratora, gdzie powinien być administratorem tylko do odczytu.

Dla Dodaj/Usuń, a aby ich przyciski znikają, prawdopodobnie również dodać

def has_add_permission(self, request): 
     # Nobody is allowed to add 
     return False 
    def has_delete_permission(self, request, obj=None): 
     # Nobody is allowed to delete 
     return False 

PS: W ModelAdmin, jeśli has_change_permission (wyszukiwanie lub Twój override) zwraca False, don” t dostać się do widoku zmiany obiektu - a link do niego nie zostanie nawet wyświetlony. Byłoby naprawdę fajnie, gdyby to zrobił, a domyślne get_readonly_fields() sprawdził uprawnienia do zmiany i ustawił wszystkie pola do odczytu w tym przypadku, jak wyżej. W ten sposób niezmienniki mogliby przynajmniej przeglądać dane ... biorąc pod uwagę, że obecna struktura administracyjna zakłada view = edit, jak wskazuje jääni- zism, prawdopodobnie wymagałoby to wprowadzenia uprawnienia "view" na górze add/change/delete ...

EDIT: Jeśli chodzi o ustawienie wszystkich pól tylko do odczytu, ale również niesprawdzone patrząc obiecująca:

readonly_fields = MyModel._meta.get_all_field_names() 

EDIT: Oto kolejny jeden

if self.declared_fieldsets: 
    return flatten_fieldsets(self.declared_fieldsets) 
else: 
    return list(set(
     [field.name for field in self.opts.local_fields] + 
     [field.name for field in self.opts.local_many_to_many] 
    )) 
+1

P.S .: Teraz utworzyłem żądanie funkcji w tym celu https://code.djangoproject.com/ticket/17295 –

+1

Uwaga: Metoda get_formset jest zdefiniowana tylko dla InlineModelAdmin –

+0

Cześć, dziękuję za tę kompilację opcji. Może być uprzejmy, ale również podać linki do odpowiedzi, z których dostałeś kawałki, ponieważ widzę, że nie wszystkie są twoje. Kolejną zaletą byłoby to, że czytelnicy mogli również zobaczyć komentarze, które inni poczynili na temat każdej z sugestii. – steps

2

Możesz dostosować swoje klasy ModelAdmin za pomocą atrybutu readonly_fields. Aby uzyskać więcej informacji, patrz this answer.

+0

, ale czy istnieje sposób na uczynienie ** całości ** modelu jako read_only, bez konieczności dodawania wszystkich jego atrybutów do listy readonly_fields? – juliomalegria

+1

Istnieje, ale nie jest łatwo. Jesteś w stanie tworzyć własne uprawnienia w Django, ale jeśli chodzi o administrację, nie jest to banalne. Django zakłada, że ​​jeśli ludzie mają dostęp do zawartości w interfejsie administratora, mogą edytować ją. Możesz spróbować sugestii z [to pytanie] (http://stackoverflow.com/questions/4334049/make-a-django-model-read-only), jeśli czujesz się odważny. IMO łatwiej jest jawnie ustawić wszystkie pola tylko do odczytu i przejść dalej. – jathanism

0

miałem podobny scenariusz, w którym:

  1. Użytkownik powinien być w stanie stworzyć model obiektów
  2. Użytkownik powinien móc przeglądać listę modelu obiektów
  3. użytkownika SHOULD'NT móc edytować obiekt po to został stworzony

1 Nadpisanie widoku zmiany

Ponieważ możliwe jest zastąpienie change_view() w usłudze ModelAdmin, możemy to wykorzystać, aby zapobiec edycji instancji modelu po ich utworzeniu. Oto przykład, którego użyłem:

def change_view(self, request, object_id, form_url='', extra_context=None): 
    messages.error(request, 'Sorry, but editing is NOT ALLOWED') 
    return redirect(request.META['HTTP_REFERER']) 

2.Warunkowo Zmiany Edytuj uprawnienia

ja też sobie sprawę, że docs interpretować wyniku ModelAdmin.has_change_permission() na różne sposoby:

Should return True if editing obj is permitted, False otherwise. If obj is None, should return True or False to indicate whether editing of objects of this type is permitted in general (e.g., False will be interpreted as meaning that the current user is not permitted to edit any object of this type).

Czyli mogę sprawdzić czy obj jest None, w którym to przypadku wrócę True, inaczej wrócę False , a to w efekcie pozwala użytkownikom przeglądać listę zmian, ale nie może edytować ani wyświetlać zmiany, gdy instancja modelu zostanie zapisana.

def has_change_permission(self, request, obj = None, **kwargs): 
    if obj is None: 
     return True 
    else: 
     return False 

Choć myślę to może również zastąpić żadnych MODEL_can_change uprawnienia pozwalające niechcianych oczu od oglądania Zamiana listę?

-1

Według mojego testu na Django 1.8 nie możemy użyć następujących jak zauważono na Odpowiedź # 3, ale to działa na Django 1.4:

##  self.get_formset(request, obj)  ## 
answer 3 needs fix. Generally, alternative codes for this issue about below section 
##   form = self.get_formset(request, obj).form ## 
##   fields = form.base_fields.keys()    ## 

Może być coś takiego:

#~ (A) or 
[f.name for f in self.model._meta.fields] 

#~ (B) or 
MyModel._meta.get_all_field_names() 

#~ (C) 
list(set([field.name for field in self.opts.local_fields] + 
         [field.name for field in self.opts.local_many_to_many]   
)) 
3

Jako „view uprawnienia "will not make it into Django 1.11, niestety, oto rozwiązanie, które powoduje, że modelAdmin jest tylko do odczytu przez, co powoduje zapisywanie zmian modelu i dodawanie wpisów historii historii modelu a no-op.

def false(*args, **kwargs): 
    """A simple no-op function to make our changes below readable.""" 
    return False 

class MyModelReadOnlyAdmin(admin.ModelAdmin): 
    list_display = [ 
     # list your admin listview entries here (as usual) 
    ] 
    readonly_fields = [ 
     # list your read-only fields here (as usual) 
    ] 

    actions = None 
    has_add_permission = false 
    has_delete_permission = false 
    log_change = false 
    message_user = false 
    save_model = false 

(. UWAGA: nie pomylić pomocnika false no-op z False wbudowanego polecenia Jeśli nie sympatyzować z funkcji pomocnika poza klasą przenieść go do klasy, nazwać no_op lub coś innego, albo zastąpić dotkniętych atrybuty zwykłymi def s Mniej DRY, ale jeśli to nie obchodzi ...)

To będzie:.

  1. usunąć działania na liście rozwijalnej (Z „delete”) w widoku listy
  2. Disallow dodając nowy model wjazdowe
  3. Disallow usuwając istniejący model wjazdowe
  4. uniknąć tworzenia wpisów dziennika w historii modelu
  5. uniknąć wyświetlania „został pomyślnie zmieniony” wiadomości po zapisaniu
  6. Unikaj zapisywania zmian changeform do bazy

To nie będzie:

  • wyjąć lub wymienić dwa przyciski „Zapisz i kontynuuj edycję” i „SAVE” (co byłoby miło, aby poprawić doświadczenia użytkownika)

Zauważ, że get_all_field_names (jak wspomniano w przyjętym odpowiedzi) był removed in Django 1.10. Testowano z Django 1.10.5.