Skip to content
Advertisement

How to limit choices of ForeignKey choices for Django raw_id_field

How do you limit what choices are shown for ForeignKey fields in Django’s admin when they’re displayed using the raw_id_fields option?

When rendered as a select box, it’s simple to define a custom ModelForm to set that field’s queryset value with the choices to want. However, this queryset appears to be completely ignored when rendered using raw_id_fields. It generates a link to that ForeignKey‘s model, allowing you to select any record from that model via a popup window. You can still filter these values by customizing the URL, but I can’t find a way to do this via a ModelAdmin.

Advertisement

Answer

I use similar to FSp approach in my Django 1.8 / Python 3.4 project:

from django.contrib import admin
from django.contrib.admin import widgets
from django.contrib.admin.sites import site
from django import forms

class BlogRawIdWidget(widgets.ForeignKeyRawIdWidget):
    def url_parameters(self):
        res = super().url_parameters()
        res['type__exact'] = 'PROJ'
        return res

class ProjectAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['blog'].queryset = Blog.objects.filter(type='PROJ')
        self.fields['blog'].widget = BlogRawIdWidget(rel=Project._meta.get_field('blog').remote_field, admin_site=site)

    class Meta:
        # Django 1.8 convenience:
        fields = '__all__'
        model = Project

class ProjectAdmin(admin.ModelAdmin):
    form = ProjectAdminForm
    raw_id_fields = ('blog',)

to select only blog.type == 'PROJ' as foreign key Project.blog in django.admin. Because end-users may and will to select anything, unfortunately.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement