2011-10-22 21 views
29

Ho un modello simile a questo:Django admin: rendere campo modificabile in add ma non modificare

class Product(models.Model): 
    third_party_id = models.CharField(max_length=64, blank=False, unique=True) 

che utilizza il Django predefinito chiave primaria. Voglio che gli utenti siano in grado di aggiungere prodotti impostando third_party_id nella pagina di aggiunta, ma non voglio che quel campo sia modificabile nella pagina di modifica per evitare di danneggiare il terzo_party_id. Nei documenti Django, le stesse impostazioni sembrano essere usate per aggiungere e modificare. È possibile?

risposta

40

Non impostare self.readonly_fields per evitare problemi di thread. Invece l'override metodo get_readonly_fields:

def get_readonly_fields(self, request, obj=None): 
    if obj: # obj is not None, so this is an edit 
     return ['third_party_id',] # Return a list or tuple of readonly fields' names 
    else: # This is an addition 
     return [] 
+2

Molto bello non sapeva di questo metodo. +1. Cosa possiamo fare se non esiste un metodo per sovrascrivere? Qualche strategia? Molto apprezzato. –

+1

@YUji, i metodi get_form e get_formset di ModelAdmin coprono quasi tutti i casi d'uso. Potrebbe essere necessario dare un'occhiata al codice (options.py), quei metodi non erano inclusi nei documenti nel momento in cui ho cercato una soluzione per questo argomento. – shanyu

+0

Intendevo solo in python generale se non esisteva un metodo conveniente per eseguire l'override. Solo un lock.acquire()? –

0

Non sono sicuro se questo è il modo migliore, ma è possibile definire il proprio modulo per l'amministratore. E personalizzato convalidare il third_party_id, rifiutando se è già impostata:

Admin.py

class ProductAdminForm(forms.ModelForm): 
    class Meta: 
     model = Product 

    def clean_third_party_id(self): 
     cleaned_data = self.cleaned_data 
     third_party_id = cleaned_data['third_party_id'] 
     id = cleaned_data['id'] 
     obj = Product.objects.get(id=id) 
     if obj.third_party_id != third_party_id: 
      raise ValidationError("You cannot edit third_party_id, it must stay as %s" % obj.third_party_id) 
     return third_party_id 


class ProductAdmin(admin.Admin): 
    form = [ProductAdminForm,] 
+0

Ho accettato la risposta di @ shanyu, ma grazie! –

5

Quanto sopra è utile (la risposta di Shanyu utilizzando get_readonly_fields), tuttavia non funziona correttamente se utilizzato in "StackedInline". Il risultato sono due copie di qualunque campo contrassegnato in sola lettura e non è modificabile nell'istanza "aggiungi". Vedi questo bug: https://code.djangoproject.com/ticket/15602

Spero che questo risparmi qualcuno alla ricerca!

Problemi correlati