You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动将ForeignKey与OneToOneField配置为raw_id_fields?

Automatically set raw_id_fields for all ForeignKey/OneToOneField in Django Admin

Absolutely! You can build a reusable mixin that takes care of auto-populating raw_id_fields with all your model's ForeignKey and OneToOneField fields—no more manual list maintenance. Let's fix up that mixin you started with to work properly with Django's admin lifecycle:

The Complete Mixin Implementation

from django.db import models
from django.contrib import admin

class AutoRawIdFieldsMixin:
    def __init__(self, model, admin_site):
        # Call parent constructor first to initialize core admin functionality
        super().__init__(model, admin_site)
        self.setup_raw_id_fields()

    def setup_raw_id_fields(self):
        # Collect all editable ForeignKey/OneToOneField fields from the model
        raw_id_candidates = []
        # Use include_parents=False to skip fields inherited from parent models (optional)
        for field in self.model._meta.get_fields(include_parents=False):
            # Only include fields that are editable (since non-editable ones won't show up in the admin)
            if isinstance(field, (models.ForeignKey, models.OneToOneField)) and field.editable:
                raw_id_candidates.append(field.name)
        
        # Assign the collected fields to raw_id_fields as a tuple (matching Django's expected format)
        self.raw_id_fields = tuple(raw_id_candidates)

How to Use the Mixin

Just inherit the mixin first in your admin class (order matters—mixins need to come before admin.ModelAdmin):

@admin.register(DaftarSoal, site=admin_site)
class DaftarSoalAdmin(AutoRawIdFieldsMixin, admin.ModelAdmin):
    # No manual raw_id_fields needed anymore!
    pass

@admin.register(AnotherModel, site=admin_site)
class AnotherModelAdmin(AutoRawIdFieldsMixin, admin.ModelAdmin):
    pass

Customization Options

If you need to exclude specific fields from being converted to raw ID inputs, add an exclude_raw_id_fields attribute to your admin class and update the mixin like this:

class AutoRawIdFieldsMixin:
    # Default to no exclusions
    exclude_raw_id_fields = ()

    def __init__(self, model, admin_site):
        super().__init__(model, admin_site)
        self.setup_raw_id_fields()

    def setup_raw_id_fields(self):
        raw_id_candidates = []
        for field in self.model._meta.get_fields(include_parents=False):
            if (
                isinstance(field, (models.ForeignKey, models.OneToOneField)) 
                and field.editable 
                and field.name not in self.exclude_raw_id_fields
            ):
                raw_id_candidates.append(field.name)
        self.raw_id_fields = tuple(raw_id_candidates)

Then use it to exclude fields:

class DaftarSoalAdmin(AutoRawIdFieldsMixin, admin.ModelAdmin):
    # Keep 'folder' as a regular dropdown instead of raw ID
    exclude_raw_id_fields = ('folder',)

Key Notes

  • We use self.model._meta.get_fields() to inspect the model's fields directly, which is the official Django way to access model metadata.
  • Adding field.editable ensures we only include fields that would normally appear in the admin form (non-editable fields are skipped automatically).
  • Using include_parents=False is optional but useful if you want to exclude fields inherited from abstract parent models.

内容的提问来源于stack exchange,提问作者binpy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:22:49