2009-04-06 2 views
0

Ich habe ein Modell mit Feld:forms.SelectMultiple von models.CommaSeparatedIntegerField

class Movie(models.Model): 
    genre = models.CommaSeparatedIntegerField(max_length=100, choices=GENRE_CHOICES, blank=True, default=0) 
    lang = models.CommaSeparatedIntegerField(max_length=100, choices=LANG_CHOICES, blank=True, default=0) 

Und ich brauche mehrere Auswahlfelder bekommen (nicht Kontrollkästchen) aus, dass.

Eine Möglichkeit, die ich gefunden, Form von Modeladmin

class MyMovieAdminForm(forms.ModelForm): 
    genre = forms.MultipleChoiceField(choices=GENRE_CHOICES) 
    lang = forms.MultipleChoiceField(choices=LANG_CHOICES) 

class MovieAdmin(admin.ModelAdmin): 
    form = MyMovieAdminForm 

admin.site.register(Movie, MovieAdmin) 

Aber es für jedes Feld ‚Label‘ und ‚Initiale‘ deklarieren muß neu zu definieren ist, ist, dass für DRY-Prinzip nicht gut. Und ich verstehe nicht, wie kann ich den aktuellen Wert des Objekts für den Anfangswert jedes Feldes setzen?

Und andere Weise, die ich im Handbuch fand, ist formfield-overrides. Ich benutze dev Version von Stamm und ich versuche, diesen Code zu verwenden, aber es hat nicht meine Auswahlfelder ändert in der Administrationsoberfläche zu multiselect:

class MovieAdmin(admin.ModelAdmin): 
    formfield_overrides = { 
     models.CommaSeparatedIntegerField: {'widget': forms.SelectMultiple}, 
    } 

sein kann jemand wissen, was ist die beste Art und Weise wählen zu definieren mehr Felder? Vielen Dank!

Antwort

1

Ich finde keine Arbeit Antwort für models.CommaSeparatedIntegerField als forms.SelectMultiple machen. Also habe ich models.CommaSeparatedIntegerField in models.ManyToManyField geändert und das Formularfeld funktioniert sehr gut! Es ist besser geeignet in Fällen, in denen Sie Fragen zu diesem Feld stellen müssen. Entfernen

+0

+1 Das ist schön zu wissen –

0

Ich verwende das folgende für etwas-DRYer Formularbearbeitung, und es funktioniert mit 1.0. Es ist ausführlich, aber es funktioniert.

class MyMovieAdminForm(forms.ModelForm): 
    ## Meta, etc 

    def __init__(self, *args, **kwargs): 
     super(MyMovieAdminForm, self).__init__(*args, **kwargs) 
     self.fields["genre"].widget = forms.SelectMultiple(choices=foo) 
     self.fields["genre"].initial = self.instance.genre 
     # Doesn't require redefining label, etc. 
+0

I Versuchen Sie, Ihren Code zu verwenden, aber ich habe mehrere Probleme: * Wenn ich Objekt speichern, zeigt das Formular Fehler: 'invalid_choice', dass ich nicht akzeptierbare Werte auswähle, aber ich benutze richtige Optionen im Modell und in MyMovieAdminForm .__ init__ too. – ramusus

+0

Sekunde und das wichtigste Problem: Wenn ich existierende Objekte bearbeite, zeigt das Formular mir Werte aus der DB in diesen mehreren Auswahlfeldern nicht an. – ramusus

1

1) Auswahl von models.CommaSeparatedIntegerField in Modellen

2) Erstellen Sie CommaSeparatedCharField als Ersatz

class CommaSeparatedCharField(forms.CharField): 
    def to_python(self, value): 
     if value in validators.EMPTY_VALUES: 
      return u'' 
     csv = smart_unicode(','.join(value)) 
     return csv 

class CommaSeparatedSelectMultiple(forms.SelectMultiple): 
    def render(self, *args, **kwargs): 
     print args, kwargs 
     args_=list(args) 
     if type(args_[1])!=list: 
      args_[1] = args_[1].split(',') 
     return super(CommaSeparatedSelectMultiple, self).render(*args_, **kwargs) 

3) Bewerben

class MyAdmin(admin.ModelAdmin): 
    class form(forms.ModelForm): 
     def __init__(self, *args, **kwargs): 
      super(forms.ModelForm, self).__init__(*args, **kwargs) 
      for field_name, choices in [ 
       ('minutes', [(i,str(i)) for i in range(60)]), 
      ]: 
       self.fields[field_name] = CommaSeparatedCharField(
        label=self.fields[field_name].label, 
        initial=self.fields[field_name].initial, 
        widget=forms.CommaSeparatedSelectMultiple(choices=choices) 
       ) 

Arbeit schön auf 1,2 Stamm

+0

Es dauerte ein wenig zu schätzen, alle Importe zu finden, und die "Minuten" zu überarbeiten, um meinen Feldnamen zu verwenden, aber ansonsten funktioniert das gut für mich in Django 1.3. – Cerin