【问题标题】:Correct way to store multi-select results in Django model在 Django 模型中存储多选结果的正确方法
【发布时间】:2013-11-29 00:19:29
【问题描述】:

全部:

对于静态数据,与 CheckboxSelectMultiple 小部件一起使用的正确 Model 字段类型是什么?我收到了验证错误,感觉我遗漏了一些简单的东西。

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

因为它是静态数据,并且我已经准备好 ManyToManyField 具有不必要的数据库开销,所以我尝试使用模型内部定义的 choices 来执行此操作,但是当我尝试保存时,我得到了验证错误 选择一个有效的选项。 [u'5', u'6'] 不是可用的选项之一。 每次。

  • Q1:我是否必须覆盖/子类化字段才能支持此功能?
  • Q2:我是否需要自定义验证方法来支持这一点?
  • Q3:我是否因为避免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
        }

【问题讨论】:

    标签: django django-models django-forms


    【解决方案1】:

    我知道这是一个老问题,但是对于那些希望避免使用 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 的键存储在逗号分隔的字符串中。简单!

    【讨论】:

    • Django Multiselect 查询时会遇到一些困难。
    • 我在过滤数据时也遇到了困难。例如:MyModel.objects.filter(multi_sec_field=value) & 还尝试了 MyModel.objects.filter(multi_sec_field__in=list_value) 并且还尝试了 MyModel.objects。 filter(multi_sec_field__in=value) 获取空查询集。 MyModel.objects.filter().values_list('multi_sec_field') 给出列表 qs
    • 在数据库中以字符串形式存储。相应地继续: MyModel.objects.filter(Q(my_field__contains='a')&Q(my_field__contains='b'))
    • 只要我在这里,如果您正在使用 Postgres,请忽略我的回答并查看 ArrayField
    【解决方案2】:

    ManyToManyField 是正确的选择。

    理论上,您可以创建一个紧凑的表示形式,例如包含“M,W,Th”等表示形式的字符串字段,或者您将设置并解释为 7 个二进制位的整数,但这都是非常麻烦的一起工作。 ManyToManyFields 很好。

    【讨论】:

    • 谢谢。我花时间试图避免开销,但你是对的:一旦我用 M2M 尝试过,它所花的时间比写这个问题要少:)
    猜你喜欢
    • 2014-05-26
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 2022-11-12
    • 1970-01-01
    • 2012-09-04
    相关资源
    最近更新 更多