Hele model als alleen-lezen

Is er een manier om een ​​model alleen-lezen te maken in de django-beheerder? maar ik bedoel het hele model. Dus, niet toevoegen, niet verwijderen, niet veranderen, alleen de objecten en de velden zien, alles als alleen-lezen?

13
Het is een werk in uitvoering dat lijkt: github.com/django/django/pull/5297
toegevoegd de auteur Bosco, de bron

5 antwoord

ModelAdmin levert de hook get_readonly_fields() - het volgende is niet getest, mijn idee is om alle velden te bepalen zoals ModelAdmin dat doet, zonder een recursie tegen te komen met de readonly-velden zelf:

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

subclass/mixin deze admin waar het een read-only admin zou moeten zijn.

Voor toevoegen/verwijderen en om hun knoppen te laten verdwijnen, wilt u waarschijnlijk ook toevoegen

    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

P.S .: In ModelAdmin, als has_change_permission (opzoeken of uw overschrijving) False retourneert, komt u niet in de wijzigingsweergave van een object - en de koppeling ernaar zal niet eens worden getoond. Het zou eigenlijk cool zijn als dat zo was, en de standaard get_readonly_fields() controleerde de wijzigingsbevoegdheid en stelde alle velden in dat geval alleen in, zoals hierboven. Op die manier konden niet-changers op zijn minst door de gegevens bladeren ... aangezien de huidige beheerdersstructuur view = edit veronderstelt, zoals het jathanisme opmerkt, zou dit waarschijnlijk de introductie van een "view" permissie bovenop het toevoegen/wijzigen/verwijderen vereisen ...

EDIT: over het instellen van alle velden readonly, ook niet getest maar ziet er veelbelovend uit:

readonly_fields = MyModel._meta.get_all_field_names()

EDIT: Hier is er nog een

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]
    ))
11
toegevoegd
PS: ik heb nu een functieverzoek gemaakt met dat doel code.djangoproject.com/ticket/17295
toegevoegd de auteur Danny W. Adair, de bron
Opmerking: get_formset-methode is alleen gedefinieerd voor InlineModelAdmin
toegevoegd de auteur Vajk Hermecz, de bron
Hallo, bedankt voor deze compilatie van opties. Het zou echter wel beleefd kunnen zijn om ook de links naar de antwoorden te geven waar je de stukken van hebt gekregen, omdat ik zie dat ze niet helemaal van jou zijn. Een ander voordeel is dat de lezers ook de opmerkingen van anderen over elk van de suggesties kunnen zien.
toegevoegd de auteur steps, de bron
Werkt niet in Django 1.11 - AttributeError: 'ReadOnlyAdmin' object heeft geen attribuut 'declared_fieldsets'
toegevoegd de auteur turbotux, de bron

Als "weergavemachtigingen" komt Django 1.11 niet voor de dag, helaas , hier is een oplossing die ervoor zorgt dat uw ModelAdmin alleen-lezen door zowel modelwijzigingen opslaat als logboekvermeldingen voor modelgeschiedenis toevoegt een nee-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

( OPMERKING: vergis je niet in de false no-op helper met de False ingebouwd. Als je geen sympathie hebt voor de helperfunctie buiten de klasse verplaatst het naar de klasse, noemt het no_op of iets anders, of heft de aangetaste attributen op met de gebruikelijke def s. Minder DROOG, maar als het je niet kan schelen. ..)

Dit zal:

  1. verwijder de vervolgkeuzelijst met acties (met "verwijderen") in de lijstweergave
  2. niet toestaan ​​nieuwe modelboekingen toe te voegen
  3. niet toestaan ​​bestaande modelboekingen te verwijderen
  4. Vermijd het maken van logboekitems in de modelgeschiedenis
  5. Vermijd het weergeven van "is succesvol veranderd" berichten na het opslaan
  6. vermijd het opslaan van wijzigingsformulieren in de database

Het zal niet:

  • verwijder of vervang de twee knoppen "Opslaan en doorgaan met bewerken" en "OPSLAAN" (wat handig zou zijn om de gebruikerservaring te verbeteren)

Merk op dat get_all_field_names (zoals vermeld in het geaccepteerde antwoord) verwijderd in Django 1.10 . Getest met Django 1.10.5.

3
toegevoegd

U kunt uw klassen ModelAdmin aanpassen met de readonly_fields -kenmerk. Zie dit antwoord voor meer informatie.

2
toegevoegd
Dat is er, maar niet gemakkelijk. Je kunt aangepaste rechten maken in Django, maar als het gaat om de beheersite is het niet-triviaal. Django gaat ervan uit dat als mensen inhoud mogen bekijken in de admin-interface, ze deze ook mogen bewerken. Je kunt de suggestie van deze vraag proberen als je je gedurfd voelt. IMO het is gewoon makkelijker om alle velden expliciet in te stellen en alleen verder te gaan.
toegevoegd de auteur jathanism, de bron
maar is er een manier om het hele model als read_only te maken, zonder alle attributen aan de readonly_fields-lijst toe te voegen?
toegevoegd de auteur juliomalegria, de bron

Volgens mijn test op Django 1.8 kunnen we het volgende niet gebruiken zoals genoteerd op antwoord 3, maar het werkt op 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()              ##

Kan iets zijn als:

#~ (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]         
  ))
1
toegevoegd

Ik had een soortgelijk scenario waarin:

  1. De gebruiker zou in staat moeten zijn om de modelobjecten te maken
  2. Gebruiker moet de lijst van modelobjecten kunnen bekijken
  3. Gebruiker MOET een object niet kunnen bewerken nadat het is gemaakt

1. De wijzigingsweergave negeren

Omdat het mogelijk is om de change_view() in een ModelAdmin te overschrijven, kunnen we die gebruiken om te voorkomen dat modelinstances worden bewerkt nadat ze zijn gemaakt. Hier is een voorbeeld dat ik heb gebruikt:

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. Voorwaardelijke bewerkingsrechten wijzigen

Ik realiseerde me ook dat de documenten het resultaat van ModelAdmin.has_change_permission() op verschillende manieren interpreteren:

Moet terugkeren naar True als het bewerken van obj is toegestaan, anders False. Als   obj is None, zou True of False moeten retourneren om aan te geven of het moet worden bewerkt   van objecten van dit type is in het algemeen toegestaan ​​(bijv. False zal zijn   geïnterpreteerd als zijnde dat de huidige gebruiker niet is toegestaan ​​om te bewerken   elk object van dit type).

Dit betekent dat ik kon controleren of obj None is, in welk geval ik True retourneer, anders retourneer ik False , en Hierdoor kunnen gebruikers de lijst met wijzigingen bekijken, maar kunnen ze het wijzigingsformulier niet bewerken of bekijken nadat de modelinstantie is opgeslagen.

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

Hoewel ik denk dat dit ook eventuele machtigingen van MODEL_can_change kan overschrijven waardoor ongewenste ogen de wijzigingslijst kunnen bekijken?

0
toegevoegd