99 votes

django admin crée un champ en lecture seule lors de la modification d'obj mais requis lors de l'ajout d'un nouvel obj

Dans admin, je voudrais désactiver un champ lors de la modification d'objet, mais le rendre obligatoire lors de l'ajout d'un nouvel objet.

Quelle est la façon de faire le django à propos de celui-ci?

195voto

Bernhard Vallant Points 18035

Vous pouvez remplacer la méthode get_readonly_fields :

 class MyModelAdmin(admin.ModelAdmin):

    def get_readonly_fields(self, request, obj=None):
        if obj: # editing an existing object
            return self.readonly_fields + ('field1', 'field2')
        return self.readonly_fields
 

3voto

Tim Diggins Points 1578

Pour info: dans le cas où quelqu'un d'autre s'exécute dans le même deux problèmes que j'ai rencontrés:

  1. Vous devez toujours déclarer tout de façon permanente readonly_fields dans le corps de la classe, comme le readonly_fields attribut de classe sera accessible à partir de la validation (voir django.contrib.admin.validation: validate_base(), ligne.213 appx)

  2. Cela ne fonctionne pas avec les Inlines que l'obj passé à get_readonly_fields() est le parent obj (j'en ai deux, plutôt hacky de faible et de solutions de sécurité à l'aide de css ou js)

0voto

David Miller Points 1245

Vous pouvez le faire en remplaçant la méthode formfield_for_foreignkey de ModelAdmin:

 from django import forms
from django.contrib import admin

from yourproject.yourapp.models import YourModel

class YourModelAdmin(admin.ModelAdmin):

    class Meta:
        model = YourModel

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        # Name of your field here
        if db_field.name == 'add_only':
            if request:
                add_opts = (self._meta.app_label, self._meta.module_name)
                add = u'/admin/%s/%s/add/' % add_opts
                if request.META['PATH_INFO'] == add:
                    field = db_field.formfield(**kwargs)
                else:
                    kwargs['widget'] = forms.HiddenInput()
                    field = db_field.formfield(**kwargs)
            return field
        return admin.ModelAdmin(self, db_field, request, **kwargs)
 

0voto

Nick Ma. Points 21

Eu un problème similaire. Je l'ai résolu avec "add_fieldsets" et "restricted_fieldsets" dans le ModelAdmin.

from django.contrib import admin  
class MyAdmin(admin.ModelAdmin):
 declared_fieldsets = None
 restricted_fieldsets = (
    (None, {'fields': ('mod_obj1', 'mod_obj2')}),
    ( 'Text', {'fields': ('mod_obj3', 'mod_obj4',)}),
 )

 add_fieldsets = (
            (None, {
             'classes': ('wide',),
             'fields': ('add_obj1', 'add_obj2', )}),
             )

Veuillez voir par ex.: http://code.djangoproject.com/svn/django/trunk/django/contrib/auth/admin.py

Mais ce n'est pas de protéger votre modèle de modifications ultérieures de "add_objX". Si vous voulez que ce trop, je pense que vous devez aller le chemin sur le Modèle de la classe de fonction "enregistrer" et vérifier les changements.

Voir: www.djangoproject.com/documentation/models/save_delete_hooks/

Greez, Nick

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X