2014-01-16 8 views
6

Das Problem ist, die Inline-Modelle zu haben, einige ihrer Felder nach anderen Modell vorgewählt zu haben.Django Admin Formular mit vordefinierten Inlines

Nehmen wir ein Beispiel machen:

class Document(models.Model): 
    DOC_TYPES = ((DC1, 'Doc type 1'), (DC2, 'Doc type 2')) 
    doctype = model.CharField(choices=DOC_TYPES, default=DC1) 

class OptionCategory(models.Model): 
    name = model.CharField() 

class Option(models.Model): 
    document = models.ForeignKey(Document) 
    option_category = models.ForeignKey(OptionCategory) 
    some_data = models.CharField() 

Angenommen, Option definiert wird inline in Dokumentenmodell Admin.

OptionCategory ist notwendig - diese können von admin hinzugefügt werden - Ich hätte gerne ein Erstellungsformular für Dokument mit so vielen Optionsmodellen in Inline-Formularen, wie es Optionskategorien gibt. Dies kann leicht mit Extras in Option Model Admin erreicht werden. Die Fragen sind:

  1. Wie Inline-Felder jeweils mit verschiedenen Optionskategorie vorgewählt?
  2. Wie man Optionen dynamisch ändert (basiert auf Document.doctype nach dem Hinzufügen ähnlicher Doctype Feld in OptionCategory) - vorzugsweise mit AJAX?
+1

Ich bin nicht total aber Sie können das gewünschte Verhalten mit [get_formsets_with_inlines] erreichen (https: // doc s.djangoproject.com/de/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_formsets_with_inlines) Methode – esauro

+0

Wo ist OptionType? Bitte machen Sie ein echtes Beispiel – vadimchin

+0

'OptionType' ==' OptionCategory'? – FallenAngel

Antwort

3
  1. Wie Inline-Felder präsentieren jeweils mit verschiedenen Optionstyp vorgewählte:

models.py

class DocType(models.Model): 
     name = models.CharField(max_length=255) 

     def __unicode__(self): 
      return self.name 


    class Document(models.Model): 
     doc_type = models.ForeignKey(DocType) 
     some_data = models.CharField(max_length=255) 

     def __unicode__(self): 
      return self.some_data 


    class OptionType(models.Model): 
     name = models.CharField(max_length=255) 
     doc_type = models.ForeignKey(DocType) 

     def __unicode__(self): 
      return self.name 


    class Option(models.Model): 
     document = models.ForeignKey(Document) 
     option_type = models.ForeignKey(OptionType) 
     some_data = models.CharField(max_length=255) 

     def __unicode__(self): 
      return self.some_data 

admin.py

class InlineOption(admin.TabularInline): 
    model = Option 
    extra = 3 

    initial = [ 
     {'some_data': 'init_val1', 'option_type': 1}, 
     {'some_data': 'init_val2'}, 
    ] 

    create_from_default = True 

    def get_formset(self, request, obj=None, **kwargs): 
     initial = self.initial[:] 

     class _Form(forms.ModelForm): 
      form_initial = initial 

      def __init__(self, *args, **kwargs): 
       if len(self.form_initial) and not 'instance' in kwargs: 
        kwargs['initial'] = self.form_initial.pop(0) 
       return super(_Form, self).__init__(*args, **kwargs) 

     if self.create_from_default: 
      if request.method == 'GET': 
       self.form = _Form 
      else: 
       self.form = forms.ModelForm 
     else: 
      self.form = _Form 

     return super(InlineOption, self).get_formset(request, obj, **kwargs) 



class AdminDocument(admin.ModelAdmin): 
    inlines = [InlineOption] 
+0

Ich sollte 'initial' nach vorhandenen Option (en) erstellen, gefiltert nach Dokument aus 'request'? – phoenix

+0

Sie können auf Anfrage filtern, aber Hauptteil - Sie müssen Anfragetyp überprüfen, weil Formular nicht mit vordefinierten Werten speichern. – vadimchin

+0

Entschuldigung für die Verzögerung, es funktioniert, aber ich musste eine Liste von Wörterbüchern in "initial" von OptionType erstellen ... Aber es gibt immer noch ein Problem. Ich habe die Document-Instanz erstellt, und wenn ich versuche, auf Änderungen zuzugreifen, verfügt sie über weitere Optionen. – phoenix

Verwandte Themen