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.