2014-11-26 15 views
6

Ho un'applicazione Django e voglio visualizzare più caselle di controllo in un'interfaccia di amministrazione di Django. Non voglio creare un modello separato per le mie scelte utilizzando ManyToManyField.Django models.CommaSeparatedIntegerField with forms.CheckboxSelectMultiple widget

models.py

from django.db import models 

STAFF_BUSINESS_TYPES = { 
    (1, "Foo"), 
    (2, "Bar"), 
    (3, "Cat"), 
    (4, "Dog") 
} 

class Business(models.Model): 
    name = models.CharField(max_length=255, unique=True) 
    business_types = models.CommaSeparatedIntegerField(max_length=32, choices=STAFF_BUSINESS_TYPES) 

forms.py

from business.models import Business, STAFF_BUSINESS_TYPES 
from django.forms import CheckboxSelectMultiple, ModelForm, MultipleChoiceField 

class BusinessForm(ModelForm): 
    business_types = MultipleChoiceField(required=True, widget=CheckboxSelectMultiple, choices=STAFF_BUSINESS_TYPES) 

    class Meta: 
     model = Business 
     fields = ['name', 'business_types'] 

    def clean_business_types(self): 
     data = self.cleaned_data['business_types'] 
     cleaned_data = ",".join(data) 
     return cleaned_data 

admin.py

from django.contrib import admin 
from business.models import Business 
from business.forms import BusinessForm 

@admin.register(Business) 
class BusinessAdmin(admin.ModelAdmin): 
    form = BusinessForm 

Tuttavia, quando tento di aggiungere un'attività con tipo "Bar":

Selezionare una scelta valida. 1 non è una delle scelte disponibili.

Allo stesso modo con cui si tenta di aggiungere un business con più valori selezionati:

Selezionare una scelta valida. 1,2 non è una delle scelte disponibili.

In che modo 1 non è una scelta valida, considerando (1, "Foo") è nelle mie scelte? È invalido utilizzare il campo intero separato da virgola di Django?

risposta

2

Ho lavorato in un problema simile e qui va la mia soluzione:

# coding: utf-8 
# python2/django1.6.5 

""" 
    That's a first solution I got to use CommaSeparatedIntegerFields with SelectMultiple widget. 
    My intension is to change this solution to a custom Widget that inherits from SelectMultiple. 
    *** It still needs refactoring *** 
""" 

models.py

from django.db import models 

MY_CHOICES = (
    (1, 'escolha1'), 
    (2, 'escolha2'), 
    (3, 'escolha3'), 
    (4, 'escolha4'), 
    (5, 'escolha5'), 
) 

class MeuConteudo(models.Model): 
    meu_campo = models.CommaSeparatedIntegerField(
     blank=True, max_length=255, 
    ) 

forms.py

from django import forms 
from minhaapp.models import MeuConteudo, MY_CHOICES 


class CommaSeparatedSelectInteger(forms.MultipleChoiceField): 
    def to_python(self, value): 
     if not value: 
      return '' 
     elif not isinstance(value, (list, tuple)): 
      raise ValidationError(
       self.error_messages['invalid_list'], code='invalid_list' 
      ) 
     return ','.join([str(val) for val in value]) 

    def validate(self, value): 
     """ 
     Validates that the input is a string of integers separeted by comma. 
     """ 
     if self.required and not value: 
      raise ValidationError(
       self.error_messages['required'], code='required' 
      ) 

     # Validate that each value in the value list is in self.choices. 
     for val in value.split(','): 
      if not self.valid_value(val): 
       raise ValidationError(
        self.error_messages['invalid_choice'], 
        code='invalid_choice', 
        params={'value': val}, 
       ) 

    def prepare_value(self, value): 
     """ Convert the string of comma separated integers in list""" 
     return value.split(',') 


class MeuConteudoMultipleForm(forms.ModelForm): 
    meu_campo = CommaSeparatedSelectInteger(
     choices=MY_CHOICES, 
     widget=forms.SelectMultiple 
    ) 

    class Meta: 
     model = MeuConteudo 

admin.py

from forms import MeuConteudoMultipleForm 
from minhaapp.models import MeuConteudo 
from minhaapp.forms import MeuConteudoMultipleForm 


class MeuConteudoAdmin(admin.ModelAdmin): 
    form = MeuConteudoMultipleForm 


admin.site.register(MeuConteudo, MeuConteudoMultipleForm) 

https://gist.github.com/romulocollopy/bffe38fa72af5bc427e1