Django - 模型的选择

时间:2011-04-25 07:44:45

标签: django django-models choice multiple-choice

我一直在搜索和查看文档,但我想在此处询问并确认最佳解决方案。

尝试定义模型选择。

  1. '是,不,不确定'选择无线电选择
  2. 如何定义多项选择
  3. 简单示例: 在我的models.py中,我有

    class Property(models.Model):
        name = models.CharField()
    
    class Feature(models.Model):
        YES_CHOICES = (       # example of 1, there can be only one selection
            ('YES', 'Yes'),
            ('NO', 'No'),
            ('NOT_SURE', 'Not Sure')
        )
        PARKING_CHOICES = (    # example of 2, there can be multiple selections
            ('GARAGE', 'Garage'),
            ('STREET', 'Street'),
            ('PRIVATE_LOT', 'Private Lot'),
            ('VALET', 'Valet'),
        )
    
        nearby_school = models.CharField(max_length=8, choices=YES_CHOICES)
        parking_options = models. MultipleChoiceField(choices=PARKING_CHOICES)
    
    class PropertyFeature(models.Model)
        property = models.ForeignKey(Property)
        feature = models.ForeignKey(Feature)
        ...
    

    那些最好的方法吗?

    1. 我应该使用NullBooleanField代替是,不,不确定问题吗?
    2. 这是定义和存储多项选择答案的正确方法吗?有时候,我看到人们使用了很多很多物体。
    3. 只想使用Django提供的最有效,最简单的方法。

2 个答案:

答案 0 :(得分:5)

18个月左右之后,现在有更好的方法来处理Django中的choices; Łukasz Langa's dj.choices。它的一个使用示例,来自blog post introducing the project

from dj.choices import Choices, Choice

class Gender(Choices):
    male = Choice("male")
    female = Choice("female")
    not_specified = Choice("not specified")

class User(models.Model):
    gender = models.IntegerField(choices=Gender(),
            default=Gender.not_specified.id)

    def greet(self):
        gender = Gender.from_id(self.gender)
        if gender == Gender.male:
            return 'Hi, boy.'
        elif gender == Gender.female:
            return 'Hello, girl.'
        else:
            return 'Hey there, user!'

但是,这仍然无法用于多项选择。

答案 1 :(得分:1)

是的,NullBoolean是合适的,但如果有更多选项不符合NullBoolean的个人资料,我赞成IntegerField以提高选项的可读性和一致性

Null可以直观地表示n/a,但是当您添加更多单选问题时,我认为使用IntegerField映射到静态变量更为直观。

对于这种类型的场景,用户可能会根据这些功能过滤属性,因此在动态查询中不必使用特殊情况Null非常有用。

示例:

...filter(Q(nearby_school__isnull=True) | Q(nearby_school='NO')),
    other_choice='SOME_CHOICE')
# vs
...filter(Q(nearby_school=Feature.NOT_SURE) | Q(nearby_school=Feature.NO)), 
    other_choice=Feature.SOME_CHOICE)

这篇古老的帖子仍然是一个很好的参考: http://www.b-list.org/weblog/2007/nov/02/handle-choices-right-way/

class Feature(models.Model):
    YES = 0
    NO = 1
    NOT_SURE = 2
    SOMETIMES = 3
    YES_CHOICES = ( 
        (YES, 'Yes'),
        (NO, 'No'),
        (NOT_SURE, 'Not Sure'),
        (SOMETIMES, 'Sometimes'), # extensible.
    )

对于多选字段,我认为使用m2m字段是最简单/最好的方法。

您可以设置forms.MultipleChoiceField将数据存储为逗号分隔字段&适当显示,但您可以轻松查询m2m字段这一事实是一个巨大的好处+它可以直接使用ModelMultipleChoiceField