在Django模型中存储多选结果的正确方法

时间:2013-11-29 00:19:29

标签: django django-models django-forms

所有

用于静态数据的Model小部件的正确CheckboxSelectMultiple字段类型是什么?我收到验证错误,觉得我错过了一些简单的事情。

该应用程序是一个简单的Django 1.6应用程序,其中Campground对象可以有多个eligible_days(例如,网站#123可能在周一和周二可用,而网站#456可用于Weds至周五)。

因为它是静态数据而且我已经准备好ManyToManyField有不必要的数据库开销,我试图用模型中定义的choices来做这个,但是当我尝试保存时,我得到了验证错误选择有效选项。 [u'5',u'6']不是可用的选择之一。每次。

  • Q1:我是否必须覆盖/子类化字段才能支持此功能?
  • Q2:我是否需要自定义验证方法来支持此功能?
  • 问题3:我是否通过避免ManyToManyField为自己做了不必要的事情?

感谢您的帮助! /米

models.py

class CampgroundQuery(models.Model):
SUN = 0
MON = 1
TUE = 2
WED = 3
THU = 4
FRI = 5
SAT = 6

DAYS_OF_WEEK_CHOICES = (
    (SUN, 'Sunday'),
    (MON, 'Monday'),
    (TUE, 'Tuesday'),
    (WED, 'Wednesday'),
    (THU, 'Thursday'),
    (FRI, 'Friday'),
    (SAT, 'Saturday'),
)

# loads choices from defined list
eligible_days = models.CharField(max_length=14,choices=DAYS_OF_WEEK_CHOICES,
    blank=False, default='Saturday')
campground_id = models.SmallIntegerField()
stay_length = models.SmallIntegerField()
start_date = models.DateField()
end_date = models.DateField()

admin.py

from django.contrib import admin
from searcher.models import CampgroundQuery
from forms import CampgroundQueryAdminForm

class CampgroundQueryAdmin(admin.ModelAdmin):
    form = CampgroundQueryAdminForm

admin.site.register(CampgroundQuery, CampgroundQueryAdmin)

forms.py

from django import forms
from django.contrib import admin
from searcher.models import CampgroundQuery

class CampgroundQueryAdminForm(forms.ModelForm):
    class Meta:
        model = CampgroundQuery
        widgets = {
            'eligible_days': forms.widgets.CheckboxSelectMultiple
        }

2 个答案:

答案 0 :(得分:4)

我知道这是一个老问题,但是对于那些希望避免使用ManyToManyField的人来说,有一个包来执行此操作django-multiselectfield,它可以快速轻松地实现。

forms.py

from multiselectfield import MultiSelectFormField

class MyForm(forms.ModelForm):
    my_field = MultiSelectFormField(choices=MyModel.MY_CHOICES)

models.py

from multiselectfield import MultiSelectField

class MyModel(models.Model):
    MY_CHOICES = (
        ('a', "A good choice"),
        ...
        ('f', "A bad choice"),
    )
    my_field = MultiSelectField(choices=MY_CHOICES, max_length=11)

那就是它!它将MY_CHOICES的键存储在逗号分隔的字符串中。简单!

答案 1 :(得分:0)

ManyToManyField是正确的选择。

理论上你可以创建一个紧凑的表示形式,比如包含像“M,W,Th”这样的表示的字符串字段,或者你将设置和解释为七个二进制位的整数,但这对你来说都是一个巨大的麻烦。与...合作。 ManyToManyFields很好。