根据字段值更改Django模型中的选择

2024-09-28 03:18:59 发布

您现在位置:Python中文网/ 问答频道 /正文

例如,如果我有一个课堂总结

类摘要的每个实例可以是一个主题:

    subjects = (
        ('english', 'אנגלית'),
        ('bible', 'תנ"ך'),
        ('history', 'היסטוריה'),
        ('civics', 'אזרחות'),
        ('language', 'לשון'),
        ('literature', 'ספרות'),
    )


class Summary(models.Model):
...
subject = models.CharField(max_length=20, choices=subjects)
...

现在我决定要为每个主题硬编码一些主题,所以如果Summary.subject = "literature"我想添加一个字段

^{pr2}$

做出如下选择:

literature_subtopics = (
    ('poems', 'שירה'),
    ('short_stories', 'סיפורים קצרים'),
    ('plays', 'מחזות'),
    ('novels', 'נובלות'),
)

如果主题是英语,那么english_subtopics将用于选项字段。在

我想硬编码所有这些部门,因为它们不会每几年更改一次以上,如果有的话,将它们存储在数据库中没有任何意义。在

我需要为每个主题设置所有这些分区,并让Django适当地为子主题设置choices字段。在

我可以重写init方法来实现这一点吗?我听说那是个坏主意,会弄坏东西。在


Tags: 实例编码主题englishmodelssummaryhistorybible
2条回答

即使数据不经常更改,将数据放入数据库并将Python放入Python文件似乎是最自然的做法。你提出的解决方案看起来像是在和Django想做的事情做斗争。在

如何看待数据库解决方案?在

class Subject(models.Model):
    parent = models.ForeignKey("self")
    name = models.CharField(max_length=100)
    hebrew_name = models.CharField(max_length=100)

class Summary(models.Model):
    ...
    subject = models.ForeignKey("Subject")
    ...

class SubjectForm(forms.Form):
    subject = forms.ModelChoiceField(queryset=Subject.objects.none())
    ...

    def __init__(self, *args, **kwargs): # see http://stackoverflow.com/a/4880869/1477364
        sub = kwargs.pop('parent_subject')
        super(SubjectForm, self).__init__(*args, **kwargs)
        parent_subject = Subject.objects.get(name=sub)
        sub_subjects = Subject.objects.filter(parent=parent_subject)
        self.fields['subject'].queryset = forms.ModelChoiceField(queryset=sub_subjects)

请注意,该代码意味着将始终有一个父主题传递给SubjectForm。(您需要一个“根”主题。)

您可以使用函数动态设置选项。在

# models.py

def get_choices():
    choices_tuple_list = []
    ... # your logic to define choices
    return choices_tuple_list

class Summary(models.Model):
    ... # Summary definition
    subject = models.CharField(max_length=20, blank=True)

    def __init__(self, *args, **kwargs):
        super(Summary, self).__init__(*args, **kwargs)
        self._meta.get_field_by_name('subject')[0]._choices = get_choices()

See docs

相关问题 更多 >

    热门问题