Domanda

Recentemente ho iniziato a utilizzare Django per amministrare una grande applicazione esistente che è stata cresciuta organicamente nel corso degli anni utilizzando twisted.web.Ho iniziato a sperimentare con Django e la sua interfaccia di amministrazione automatica e sono rimasto molto soddisfatto dei risultati.

Una cosa che sembra mancare per i miei scopi è la capacità di fornire agli utenti l'accesso in sola lettura ai dati.Ad esempio, abbiamo un ruolo in cui le persone possono accedere e creare ordini di acquisto.Devono inoltre essere in grado di visualizzare, ma non di modificare, altri dati relativi a clienti o prodotti.

Come creerei le autorizzazioni di "visualizzazione" nell'amministratore di Django in modo che gli utenti possano modificare i dati per alcune tabelle, pur avendo accesso in sola lettura ad altre?

Aggiornamento:Django Admin sembra darmi il CUD di un'interfaccia CRUD.Come posso ottenere la parte di sola lettura con autorizzazioni e gruppi associati?

Aggiornamento 2010-febbraio-12:Django 1.2 ora includerà la sola lettura.Dettagli di seguito.


Ho risposto alla mia stessa domanda, immagino.Spostando il contenuto in una risposta reale di seguito.

È stato utile?

Soluzione 5

La possibilità di aggiungere i campi di sola lettura alla vista di amministrazione è ora incluso in Django versione 1.2.

Vedere biglietto numero 342 http://code.djangoproject.com/ticket/342

Vedi il numero di modifiche 11965 http://code.djangoproject.com/changeset/11965

Vedere la documentazione http: //docs.djangoproject .com / it / dev / ref / contrib / admin / # django.contrib.admin.ModelAdmin.readonly_fields

Altri suggerimenti

Ecco come ho modificato Django 1.0.2 per aggiungere i permessi di "visualizzazione".Siamo spiacenti, non è disponibile alcuna differenza.

[X]1.Aggiunta "visualizzazione" all'elenco dei permessi predefiniti

#./contrib/auth/management/__init__.py
def _get_all_permissions(opts):
    "Returns (codename, name) for all permissions in the given opts."
    perms = []
    for action in ('add', 'change', 'delete', 'view'):
        perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
    return perms + list(opts.permissions)

[X]2.Verifica che l'autorizzazione "visualizzazione" venga aggiunta a tutti i modelli

run manage.py syncdb

Ho confermato che l'autorizzazione di visualizzazione è ora aggiunta per tutte le tabelle nella tabella auth_permissions

[X] 3.Aggiungi "get_view_permission" alla classe del modello predefinita.

Aggiunto get_view_permission alla classe del modello.Puoi trovarlo nel file ./db/models/options.py Questo viene utilizzato dalla classe admin nel passaggio successivo.

def get_view_permission(self):
    return 'view_%s' % self.object_name.lower()

[X]4.Aggiungi "has_view_permission" alla classe di amministrazione predefinita

Giusto per essere coerente aggiungerò "has_view_permission" al sistema.Sembra che dovrebbe essere da qualche parte dentro contrib/admin/options.py.Assicurati che se l'utente dispone dell'autorizzazione di modifica, le autorizzazioni di visualizzazione vengono automaticamente implicite.

# /contrib/admin/options.py
# Added has_view_permissions
def has_view_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change or view
    the given Django model instance.

    If `obj` is None, this should return True if the given request has
    permission to change *any* object of the given type.
    """
    opts = self.opts
    return self.has_change_permission(request, obj) or \
        request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())

# modified get_model_perms to include 'view' too.
# No idea where this may be used, but trying to stay consistent
def get_model_perms(self, request):
        """
        Returns a dict of all perms for this model. This dict has the keys
        ``add``, ``change``, and ``delete`` and ``view`` mapping to the True/False
        for each of those actions.
        """
        return {
            'add': self.has_add_permission(request),
            'change': self.has_change_permission(request),
            'delete': self.has_delete_permission(request),
            'view': self.has_view_permission(request),
        }

# modified response_add function to return the user to the mode list
# if they added a unit and have view rights
... 
    else:
        self.message_user(request, msg)

        # Figure out where to redirect. If the user has change permission,
        # redirect to the change-list page for this object. Otherwise,
        # redirect to the admin index.
        #if self.has_change_permission(request, None):
        if self.has_change_permission(request, None) or self.has_view_permission(request, None):
            post_url = '../'
        else:
            post_url = '../../../'
        return HttpResponseRedirect(post_url)

 # modified the change_view function so it becomes the details 
 # for users with view permission

    #if not self.has_change_permission(request, obj):
    if not (self.has_change_permission(request, obj) or (self.has_view_permission(request, obj) and not request.POST)):
        raise PermissionDenied


  # modified the changelist_view function so it shows the list of items
  # if you have view permissions
def changelist_view(self, request, extra_context=None):
    "The 'change list' admin view for this model."
    from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
    opts = self.model._meta
    app_label = opts.app_label
    #if not self.has_change_permission(request, None):
    if not (self.has_change_permission(request, None) or self.has_view_permission(request, None)):
        raise PermissionDenied

[X]5.Aggiorna il modello predefinito per elencare i modelli se l'utente dispone dell'autorizzazione di visualizzazione

Ho modificato il modello predefinito in contrib/admin/templates/admin/index.html.Questo potrebbe anche essere gestito copiando il file nella directory dei modelli locali.Ho apportato modifiche in entrambi, quindi ne ho una copia se un aggiornamento successivo sovrascrive le mie modifiche.

 {% for model in app.models %}
            <tr>
            {% if model.perms.change %}
                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
            {% else %}
                {% if model.perms.view %}
                    <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
                {% else %}
                    <th scope="row">{{ model.name }}</th>
                {% endif %}
            {% endif %}

[X] 6.Conferma che l'utente può "visualizzare" ma non "modificare" il modello

Trovato contrib/admin/templatetags/admin_modify.py sembra controllare la visualizzazione o meno dei pulsanti salva/salva e continua.Modificato il campo "salva" dall'impostazione predefinita sempre True, per verificare il contesto e le autorizzazioni.L'utente dovrebbe essere in grado di salvare se ha apportato modifiche o ha aggiunto autorizzazioni.

 'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])

[X]7.Rimuovi il pulsante "Salva e aggiungi un altro" se l'utente sta visualizzando un elemento

Modificato nuovamente contrib/admin/templatetags/admin_modify.py.Non so cosa significhi "save_as", quindi forse ho rotto qualcosa, ma sembra funzionare.

    #'show_save_and_add_another': context['has_add_permission'] and
    #                    not is_popup and (not save_as or context['add']) ,
    'show_save_and_add_another': not is_popup and
        (( change and context['has_change_permission']) or (context['add'] and context['has_add_permission']))
        and
        (not save_as or context['add']),

[X]8.Modifica l'autorizzazione "visualizzazione" per rendere il modulo di sola lettura

Se l'utente dispone dell'autorizzazione "visualizza" e "modifica", non fare nulla.La modifica sostituisce la visualizzazione.

Se l'utente dispone dell'autorizzazione "visualizza" senza "modifica", modifica i moduli predefiniti e aggiungi attributi DISABLED o READONLY agli elementi del modulo.Non tutti i browser lo supportano, ma per i miei scopi posso richiedere che gli utenti utilizzino quello giusto. Esempio disabilitato/di sola lettura

Ho scoperto che non tutti i browser rispettano la "sola lettura", quindi imposta alcuni controlli su sola lettura, altri su disabilitati.Ciò consente agli utenti di copiare i dati dai controlli di testo, se necessario.

#/django/contrib/admin/templates/admin/change_form.html

{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}

</div>
</form></div>
{% if has_view_permission and not has_change_permission %}
    <script type="text/javascript">
    jQuery('input:text').attr('readonly', 'readonly');
    jQuery('textarea').attr('readonly', 'readonly');
    jQuery('input:checkbox').attr('disabled', true);
    jQuery('select').attr('disabled', true);
    jQuery('.add-another').hide();
    </script>
{% endif %}

Questo frammento renderà superutente l'unico ad avere accesso in scrittura.

class AdminOwn(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return self.readonly_fields
        #get all fields as readonly
        fields = [f.name for f in self.model._meta.fields]
        return fields

E 'proprio lì in Admin. È possibile impostare le autorizzazioni per utenti e gruppi nel all'amministratore di aggiungere, modificare e cancellare i modelli specifici.

Aggiornamento: Scusa, ho frainteso la domanda, perché ho interpretato male la vista parola per dare il Django significa piuttosto che "sola lettura". Se si desidera di sola lettura con l'amministratore, penso che avrete bisogno di fare un po 'di lavoro. Vedere questo discussione, dove James Bennett (rilascio Django manager) dice:

  

Come si trovano con la ricerca della   archivi di questo elenco, questo non è   qualcosa l'interfaccia di amministrazione Django   è progettato per supportare, e così qualsiasi   soluzione sarà bisogno di venire del tutto   da voi a scrivere il proprio codice.

e

  

L'amministratore Django opera su tre   permesso: "add", "cambiamento" e   "Elimina". Non c'è un "vista ma fare   nessuna modifica" autorizzazione, quindi   non v'è alcun modo per applicare tale   restrizione senza fare significativi   codifiche personalizzate.

Il lavoro supplementare vi coinvolgerà l'aggiunta di una "sola lettura" il permesso per alcuni modelli, e cambiando i modelli di amministrazione di base per verificare se l'utente dispone che il permesso - e in caso affermativo, disabilitando alcuni controlli (come ad esempio salvare i pulsanti) e rendere gli altri sola lettura. Che impedirà bricolage casuale, ma potrebbe anche essere necessario modificare la logica server-side per controllare la stessa autorizzazione, al fine di evitare eventuali post inviati in un modo subdolo di aggirare i permessi.

È possibile creare un permesso "sola lettura" nel modello e utilizzare il codice di jasuca con una modifica:

models.py:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=256, null=True, blank=True)

    class Meta:
        permissions = (
            ('readonly_mymodel','Readonly MyModel'),
        )

admin.py:

class MyModelAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if not request.user.is_superuser and request.user.has_perm('mymodel.readonly_mymodel'):
            return [f.name for f in self.model._meta.fields]
        return self.readonly_fields

l'amministratore del aplication si deve dare il permesso di "cambiamento" e "sola lettura" per l'utente.

È possibile creare gruppi nel modulo di autenticazione. Poi, nel admin.py sulla base di login gruppo di utenti, impostare l'attributo readonly_fields del ModelAdmin. Aggiungere il metodo di has_add_permission def (auto, richiesta) per restituire false per il gruppo con il permesso di sola lettura. Dare l'add, modificare le autorizzazioni al gruppo. Essi saranno in grado di leggere solo gli attributi del modello.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top