2014-11-26 12 views
6

Tôi có ứng dụng Django và muốn hiển thị nhiều hộp kiểm tra trong giao diện quản trị của Django. Tôi không muốn tạo ra một mô hình riêng biệt cho các lựa chọn của mình bằng cách sử dụng một ManyToManyField.Mô hình Django.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 

Tuy nhiên, khi tôi cố gắng để thêm doanh nghiệp có loại "Quầy bar":

Chọn lựa chọn hợp lệ. 1 không phải là một trong những lựa chọn có sẵn.

Tương tự như vậy với khi tôi cố gắng để thêm một doanh nghiệp với nhiều giá trị được chọn:

Chọn một lựa chọn hợp lệ. 1,2 không phải là một trong những lựa chọn có sẵn.

Làm thế nào 1 không phải là lựa chọn hợp lệ, xem xét (1, "Foo") là sự lựa chọn của tôi? Là nó không hợp lệ để sử dụng Django được xây dựng trong Comma Separated Integer lĩnh vực như thế này?

Trả lời

2

Tôi đã làm việc trong một vấn đề tương tự và ở đây đi giải pháp của tôi:

# 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