2008-12-04 9 views
1

J'ai deux modèles, l'un est employé et l'autre est actif, avec plusieurs à une relation entre actif et employé. Et Asset est ajouté en tant que champ StackedInline à l'interface d'administration des employés. Y at-il de toute façon que je puisse créer un champ Asset en lecture seule dans l'administrateur des employés.Django Foreign Keys Lecture seule

Mon intention était de montrer tous les actifs que l'employé détient actuellement dans l'Admin, de sorte qu'il ne le supprimera pas accidentellement.

Répondre

0

Je pense que peut-être vous pouvez ajouter un widget personnalisé aux champs qui est juste un formulaire de base, sauf avec 'désactivé' sur tous les éléments - Je ne peux pas vous dire comment supprimer la possibilité d'ajouter de nouveaux enregistrements.

3

Edit: En fait, je ne pense pas que cela fonctionnera pour les modèles inline ..

Django ajouterons les champs en lecture seule natif de Django 1.1, qui devrait être libéré vers le milieu de Mars.

Read Only Admin Fields (http://www.djangosnippets.org/snippets/937/)

Cet extrait vous permettra de définir des champs en lecture seule dans l'admin.

+0

Merci, vous avez fait ma journée! –

2

utilisez ce code et importez-le dans admin.py en tant que ReadonlyAdmin. Il s'agit d'une forme modifiée de l'admin readonly.

from django import forms 
from django.utils.safestring import mark_safe 
from datetime import datetime 

class ReadOnlyWidget(forms.Widget): 
    def __init__(self, original_value, display_value): 
     self.original_value = original_value 
     self.display_value = display_value 
     super(ReadOnlyWidget, self).__init__() 

    def render(self, name, value, attrs=None): 
     if self.display_value is not None: 
      return unicode(self.display_value) 
     return unicode(self.original_value) 

    def value_from_datadict(self, data, files, name): 
     return self.original_value 

#to make fields foreignkey readonly 

class ReadOnlyAdminFields(object): 
    def get_form(self, request, obj=None): 
     form = super(ReadOnlyAdminFields, self).get_form(request, obj) 
     if hasattr(self, 'readonly') and obj is not None: 
      for field_name in self.readonly: 
       if field_name in form.base_fields: 
        if hasattr(obj, 'get_%s_display' % field_name): 
         display_value = getattr(obj, 'get_%s_display' % field_name)() 
        else: 
         display_value = None 
        if getattr(obj, field_name).__class__ in [unicode , long, int, float, datetime, list]: 
         form.base_fields[field_name].widget = ReadOnlyWidget(getattr(obj, field_name), display_value) 
        else: 
         form.base_fields[field_name].widget = ReadOnlyWidget(getattr(obj, field_name).id, display_value) 
      form.base_fields[field_name].required = False 
     return form 
+0

Soyez prudent avec cette solution. Essayez de vérifier si le champ est un objet, au lieu de vérifier que ce champ n'est pas un objet. –

0

Si vous souhaitez uniquement afficher les actifs d'un employé, vous pouvez changer la valeur par défaut admin django change_form.html. (Et vous pouvez également désactiver la ligne en premier)

Pour remplacer les modèles d'administration par défaut, copiez le dossier de modèle d'administration dans votre dossier de modèle de django local ($ {TEMPLATE_DIRS} dans votre setting.py)

et change_form.html, il y a ce bloc,

{% for inline_admin_formset in inline_admin_formsets %} 
{% include inline_admin_formset.opts.template %} 
{% endfor %} 

qui est utilisé pour afficher les inline, et ce que vous pouvez faire ici est, ce qui rend des informations supplémentaires, comme une liste des actifs des employés actuels, à ce modèle, et placez-les ci-dessus où la position originale des inlines.

Et maintenant la question est: comment est-ce que je rends cette information supplémentaire à ce modèle? Cela peut être fait en remplaçant la fonction change_view() dans le modèle d'administration de votre employé.

Par exemple, dans votre admin.py

class EmployeeAdmin(admin.ModelAdmin): 
    ... 

    def change_view(self, request, object_id, extra_context=None): 
     assets = Asset.objects.filter(employee=Employee.objects.get(id=object_id)) 
     context_data = {'inlines': assets, } 
     return super(EmployeeAdmin, self).change_view(request, object_id, extra_context=context_data) 

Et maintenant à votre change_form.html admin, utilisateur les balises de modèle pour afficher la extra_context de votre EmployeeAdmin.

par exemple,

{% for inline in inlines %} 
    {{ inline }} 
{% endfor %} 

{% for inline_admin_formset in inline_admin_formsets %} 
{% include inline_admin_formset.opts.template %} 
{% endfor %} 

Hope this helps, ce qui est avec django 1.2.4