2010-08-27 10 views
8

Unter der Annahme, dass ich ein solches Modell habendjango Modell Wahl Option als Multi Auswahlbox

COLORS= (
    ('R', 'Red'), 
    ('B', 'Yellow'), 
    ('G', 'White'), 
) 
class Car(models.Model): 
    name = models.CharField(max_length=20) 
    color= models.CharField(max_length=1, choices=COLORS) 

Es zeigt als Auswahlbox in der Admin-Panel aber ich würde mein Admin-Benutzer mag diese Farben Multi wählen wie viel zu-viele Beziehung, wie kann dies ohne eine ('RB', 'Red&Blue'), Art von Logik erreicht werden

Antwort

8

Kann ein Car mehrere color s haben? In diesem Fall sollte color eher ein many to many relationship sein als ein CharField. Wenn Sie andererseits etwas wie Unix permissions (d. H. Rot + Blau, Rot + Blau + Grün usw.) machen möchten, dann weisen Sie jedem davon numerische Werte zu und machen color einen integer field.

aktualisieren

(Nach dem Lesen Kommentar) Sie können einen custom form verwenden Ihr Modell in Admin anstelle des Standard-ModelForm zu bearbeiten. Dieses benutzerdefinierte Formular kann ein Mehrfachauswahl-Widget verwenden, mit dem Benutzer mehrere Farben auswählen können. Sie können dann die Methode clean() des Formulars überschreiben, um einen entsprechend verketteten Wert ('RB' usw.) zurückzugeben.

Update 2

Hier einige Code:

zuerst die Auswahl aus dem Modellfeld entfernen. Erhöhen Sie auch seine maximale Größe auf 2. Wir wollen hier keine Auswahl - wenn wir das tun, müssen wir eine Auswahl für jede Kombination von Farben hinzufügen.

class Car(models.Model): 
    ... 
    color= models.CharField(max_length=2) 

Zweitens fügen Sie eine benutzerdefinierte ModelForm in der Admin-App verwenden. Dieses Formular überschreibt die Farbe und deklariert es stattdessen als Mehrfachauswahlfeld. Wir tun müssen hier Entscheidungen treffen.

COLORS= (
    ('R', 'Red'), 
    ('B', 'Yellow'), 
    ('G', 'White'), 
) 

class CarAdminForm(ModelForm): 
    color = forms.MultipleChoiceField(choices = COLORS) 

    class Meta: 
     model = Car 

    def clean_color(self): 
     color = self.cleaned_data['color'] 
     if not color: 
      raise forms.ValidationError("...") 

     if len(color) > 2: 
      raise forms.ValidationError("...") 

     color = ''.join(color) 
     return color 

Beachten Sie, dass ich nur ein paar Validierungen hinzugefügt habe. Vielleicht möchten Sie mehr und/oder passen Sie die Validierungen an.

Schließlich registrieren Sie dieses Formular mit admin. In Ihrem admin.py:

class CarAdmin(admin.ModelAdmin): 
    form = CarAdminForm 

admin.site.register(Car, CarAdmin) 
+0

tatsächlich Mein Beispiel war schlecht, ich habe meine FARBEN für eine bessere Erläuterung aktualisiert. – Hellnar

+0

@Hellnar: * Wenn * Ihr Admin-Benutzer mehrere Farben auswählt, wie planen Sie, sie zu speichern? Oder möchten Sie nur eine Mehrfachauswahlbox, obwohl Sie nur eine Farbe speichern möchten? –

1

eine separate Tabelle Verwendung mit Farben (Rot, Blau, Grün), und, wie Sie gesagt haben, fügen Sie eine viele zu viele Beziehung? Choice-Typ ist keine Mehrfachauswahl, nur eine Zeichenfolge mit hinzugefügter Benutzeroberfläche und Prüfungen.

Oder erzeugen prozedural Ihre Auswahl mit itertools.combinations, Beispiel:

choices = zip(
    [''.join(x) for x in itertools.combinations(['','B','R','G'],2)], 
    [' '.join(x) for x in itertools.combinations(['','Blue','Red','Green'],2)], 
) 

# now choices = [(' Blue', 'B'), (' Red', 'R'), (' Green', 'G'), ('Blue Red', 'BR'), ('Blue Green', 'BG'), ('Red Green', 'RG')] 
+0

oder, besser, Auswahl = Summe ([[('.join (x),' '. Join (i [0] für i in x)) für x in itertools.combinations ([' Blau ',' Rot ',' Grün '], n)] für n in (1,2,3)], []) – makapuf

1

Für Farben Tupel, wenn Sie ganze Zahlen anstelle von Zeichen verwenden, können Sie commaseparatedintegerfield für Ihr Modell verwenden. Aber vergessen Sie nicht, commaseparatedintegerfield ist eine Datenbank-Ebene Struktur, so dass Ihr DBMS es unterstützen muss.

Documentation link...

2

Ich habe ein komplettes Arbeitsbeispiel mit sinnvollen Modelle konstruiert. Es funktioniert perfekt.Ich habe es auf Python 3.4.x und Django 1.8.4 getestet. Zuerst führe ich Admin-Panel und erstellen Datensätze für jede Option in Thema Modell

models.py

from django.db import models 

class Author(models.Model): 
    fname = models.CharField(max_length=50) 
    lname = models.CharField(max_length=80) 

    def __str__(self): 
     return "{0} {1}".format(self.fname, self.lname) 


class Thema(models.Model): 
    THEME_CHOICES = (
     ('tech', 'Technical'), 
     ('novel', 'Novel'), 
     ('physco', 'Phsycological'), 
    ) 
    name = models.CharField(max_length=20,choices=THEME_CHOICES, unique=True) 

    def __str__(self): 
     return self.name 

class Book(models.Model): 

    name = models.CharField(max_length=50) 
    author = models.ForeignKey(Author) 
    themes = models.ManyToManyField(Thema) 

    def __str__(self): 
     return "{0} by {1}".format(self.name,self.author) 

forms.py

from django import forms 

from .models import * 

class BookForm(forms.ModelForm): 
    themes = forms.ModelMultipleChoiceField(queryset=Thema.objects, widget=forms.CheckboxSelectMultiple(), required=False) 

admin.py

from django.contrib import admin 

from .models import * 
from .forms import * 

@admin.register(Author) 
class AuthorAdmin(admin.ModelAdmin): 
    pass 


@admin.register(Book)  
class BookAdmin(admin.ModelAdmin): 
    form = BookForm 


@admin.register(Thema) 
class ThemaAdmin(admin.ModelAdmin): 
    pass