简体   繁体   中英

How to limit choices to Foreign keys in Django admin

I run into a problem when using the Django admin. I'm building a small ScrumBoard. It has projects, with statuses, stories and tasks.

Consider the following model:

@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

The problem: when an admin user creates a story he will see statuses from all the projects instead of the status from one project.

To filter statuses by project, you need your story to already exist so django know which project we are talking about. If you set status nullalble, you can do like this (implying, you do save and continue on first save to set status)

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

您将需要django-smart-selects之类的东西

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM