2010-08-27 55 views
8

Suponiendo que tengo como modeloDjango como una caja de selección múltiple

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) 

Se muestra como una caja de selección en el panel de administración, sin embargo me gustaría que mi administrador fácil de realizar varias seleccionar los colores como muchos- relación de muchos a, ¿cómo se puede lograr esto sin un ('RB', 'Red&Blue'), tipo de lógica

Respuesta

8

¿Puede un Car tener múltiples color s? En ese caso, color debe ser many to many relationship en lugar de CharField. Si, por el contrario, desea hacer algo como Unix permissions (es decir, Rojo + Azul, Rojo + Azul + Verde, etc.), asigne valores numéricos a cada uno de ellos y haga de un integer field.

actualización

(Después de leer comentario) Puede utilizar un custom form para editar su modelo de administración en lugar del predeterminado ModelForm. Este formulario personalizado puede usar un widget de opción múltiple que permite a los usuarios seleccionar varios colores. A continuación, puede anular el método clean() del formulario para devolver un valor adecuadamente concatenado ('RB', etc.).

Actualización 2

Aquí hay un código:

En primer lugar, eliminar las opciones del campo del modelo. También aumente su tamaño máximo a 2. No queremos opciones aquí; si lo hacemos, entonces tendremos que agregar una opción para cada combinación de colores.

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

Segunda añadir una costumbre ModelForm a utilizar en aplicación de administración. Este formulario anulará el color y, en su lugar, lo declarará como un campo de opción múltiple. Nosotros do necesitamos opciones aquí.

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 

Tenga en cuenta que he agregado solo un par de validaciones. Es posible que desee más y/o personalizar las validaciones.

Finalmente, registre este formulario con el administrador. Dentro de su admin.py:

class CarAdmin(admin.ModelAdmin): 
    form = CarAdminForm 

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

realidad mi ejemplo fue malo, he actualizado mis COLORES para una mejor aclaración. – Hellnar

+0

@Hellnar: * si * su usuario administrador selecciona varios colores, ¿cómo planea almacenarlos? ¿O solo quieres un cuadro de selección múltiple aunque solo quieras almacenar un color? –

1

utilizar una tabla separada con colores (rojo, azul, verde), y, como usted ha dicho, agregar una relación muchos a muchos? El tipo de elección no es de opción múltiple, solo una cadena con IU y comprobaciones adicionales.

O, generar procesalmente sus opciones con itertools.combinations, ejemplo:

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

o, mejor, opciones = suma ([[('' .join (x), ''. Join (i [0] para i en x)) para x en itertools.combinations (['Azul', 'Rojo ',' Verde '], n)] para n en (1,2,3)], []) – makapuf

1

Para colores tupla, si utiliza números enteros en lugar de caracteres, es posible utilizar commaseparatedintegerfield para su modelo. Pero no olvide, commaseparatedintegerfield es una estructura de nivel de base de datos, por lo que su DBMS debe ser compatible.

Documentation link...

2

Yo he construido un ejemplo de trabajo completa con los modelos significativos. Funciona perfecto.Lo probé en Python 3.4.x y Django 1.8.4. Al principio corro panel de administración y crear registros para cada opción en el modelo Thema

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 
Cuestiones relacionadas