2016-05-31 9 views
0

zunächst lassen Sie mich das Szenario erklären: Ich arbeite in einem CRUD mit Django 1.8.7, Python 2.7 und Bootstrap als Frontend. In der Liste dieser CRUD, wenn der Benutzer die Schaltfläche Hinzufügen gedrückt hat, wird ein Modal mit einer Combo geöffnet, damit der Benutzer auswählen kann, welche Art von Objekt er erstellen möchte. Der Benutzer wählt die Option und das nächste Formular wird dynamisch geladen. Bis jetzt funktioniert es großartig. Mein Problem ist: Die Kombination, die der Benutzer in der Liste ausgewählt hat, ist eines der Felder dieses Formulars und dieses Feld kann nicht geändert werden. Es muss in der Form nur als Text sein.Django Model Form mit Nur-Lese-Eigenschaften

Beispiele:

Aktuelle Form:

Current form

Was sollte die Form sein, wenn die URL ist: domain.com/adm/products/add?category_id=2

enter image description here

Wenn die category_id über die Querystring übergeben wird, möchte ich nicht zulassen, dass der Benutzer diesen Wert bearbeiten.

Meine Frage ist: Wie kann ich das erreichen? Ich verwende CreateView für die Ansicht und ModelForm für das Formular.

Vielen Dank im Voraus für alle Tipps

+0

Es ist unklar, was Ihre Frage ist – marcusshep

+0

Bitte klären Sie Folgendes: "Der Benutzer wählt die Option" .. ist dies die Option, die Sie versuchen, Readonly zu machen? Auch wird dieser zitierte Text genau ".. und das nächste Formular wird dynamisch geladen" oder sollte es stattdessen "... und das nächste Formular ELEMENT wird dynamisch geladen". Lassen Sie mich eine wilde Vermutung nehmen, - meinen Sie, dass der "Formularelementwert", der basierend auf der anfänglichen Auswahl, die der Benutzer in der modalen Box gemacht hat, dynamisch geladen wird, wirklich als informative Textausgabe dargestellt werden sollte? –

+0

@BobbyC Ich habe die Frage mit Bildern aktualisiert, die zeigen, was ich erreichen möchte. –

Antwort

0

Ich habe den Weg gefunden. Zunächst müssen Sie ein benutzerdefiniertes Widget erstellen, das so dargestellt wird, wie Sie es möchten. In meinem Fall war das Original-Widget eine Combo (wählen), so fand ich dieses Widget:

class ReadOnlySelect(Select): 
    def render(self, name, value, attrs=None, choices=()): 
     final_attrs = self.build_attrs(attrs, name=name) 
     display = "None" 
     for option_value, option_label in chain(self.choices, choices): 
      if utf8_encode(option_value) == utf8_encode(value): 
       display = option_label 
     output = format_html('<p>%s</p><input type="hidden" value="%s" %s> ' % (display, value, flatatt(final_attrs))) 
     return mark_safe(output) 

Zweiter Schritt Sie den Standardwert für das Feld gesetzt haben, in der Create die get_initial Methode zu überschreiben:

def get_initial(self):   
    category = None   
    if self.request.method == "GET" : 
     # this method sets the initial value for the fields    
     try: 
      category = Category.objects.get(pk=self.request.GET.get('category_id')) 
     except Category.DoesNotExist: 
      raise Http404(_(u"Destination not found.")) 

    return {'category': category} 

Dritter Schritt Sie das Widget auf auf dem Gebiet verwendet werden:

class ItemForm(forms.ModelForm): 
    class Meta: 
     model = Item 
     fields = ['category','title' ] 
     widgets = { 
      'category': ReadOnlySelect(), 
     } 

Dann, wenn django lädt das Formular das Feld als Text von einem versteckten Eingang gefolgt erscheint.

0

definieren Sie einfach das Feld wieder kurz vor Meta.

class MyForm(ModelForm): 
    inp_type = forms.CharField(widget = forms.TextInput(attrs={'readonly':'readonly'})) 
    class meta: 
     model = MyModel 
     exclude = ['id']