如何在Django admin中将选择限制为外键

如何在Django admin中将选择限制为外键,django,foreign-keys,admin,Django,Foreign Keys,Admin,我在使用Django管理员时遇到问题。我在建一个小ScrumBoard。它有项目,有状态、故事和任务 考虑以下模型: @python_2_unicode_compatible class Project(models.Model): name = models.CharField(max_length=100) class Meta: verbose_name = _('Project') verbose_name_plural = _('Pro

我在使用Django管理员时遇到问题。我在建一个小ScrumBoard。它有项目,有状态、故事和任务

考虑以下模型:

@python_2_unicode_compatible
class Project(models.Model):
    name = models.CharField(max_length=100)

    class Meta:
        verbose_name = _('Project')
        verbose_name_plural = _('Projects')

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Status(models.Model):
    name = models.CharField(max_length=64) # e.g. Todo, In progress, Testing Done
    project = models.ForeignKey(Project)

    class Meta:
        verbose_name = _('Status')
        verbose_name_plural = _('Statuses')

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class Story(models.Model):
    """Unit of work to be done for the sprint. Can consist out of smaller tasks"""
    project = models.ForeignKey(Project)
    name=models.CharField(max_length=200)
    description=models.TextField()
    status = models.ForeignKey(Status)

    class Meta:
        verbose_name = _('Story')
        verbose_name_plural = _('Stories')

    # represent a story with it's title
    def __str__(self):
        return self.name

问题是:当管理员用户创建一个故事时,他将看到所有项目的状态,而不是一个项目的状态。

您需要类似的东西来按项目过滤状态,您需要您的故事已经存在,以便django知道我们在谈论哪个项目。如果您将status设置为nullable,则可以这样做(这意味着您在第一次保存时保存并继续以设置status)


这很正常,即使您自定义了管理员,在创建时您也无法猜测必须列出哪些状态。我理解问题:是否有办法预先选择项目(例如在查询字符串中或通过http post),然后显示状态表单的其余部分,而无需选择其他项目。您可以在创建后使用子集(修改时)通过自定义您的管理模型表单。您能提供一个基于子集方法的代码示例吗?它类似于吗?您可以避免创建自己的模型表单类,但由于状态是必需的,创建将无法按预期工作。(否则,您可以删除创建表单上的字段,因为django用户的大多数字段)你能举一个例子说明如何在管理中使用它吗?你的解决方案似乎“几乎”起作用。但是get_form()被调用了两次。我使用了一个类似的代码(事实上,复杂的mixin实现了这一点,自动化程度要高得多,但隐含了一些关于模型的特定定义,作为for_用户类方法…)在生产中没有问题。你有stacktrace吗?正如你所说,它被调用了两次,我想你的问题在del行上。你不能将我的代码片段用于自定义表单。(因为我每次都覆盖默认行为)(#form=MyForm)。管理员默认行为是每次生成一个新的FormClass,我依赖它。(我添加了一个快速编辑以避免双重删除)
class StatusAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(StatusAdmin, self).get_form(request, obj, **kwargs)
        if obj and obj.project:
            form.base_fields['status'].queryset = \
                form.base_fields['status'].queryset.filter(project=obj.project)
        elif obj is None and 'status' in form.base_fields: # on creation
            del form.base_fields['status']
        return form