Автоматический поиск по всем полям для всех моделей в админке django

Я хочу иметь возможность искать все модели для всех полей в администраторе Django без необходимости индивидуальной настройки ModelAdmin и полей поиска.

пример:

У меня есть все мои модели в model.py:

# This is an auto-generated Django model module.
from django.db import models

class Diagnosis(models.Model):
    id = models.BigAutoField(primary_key=True)
    code = models.CharField(max_length=255)
    starting_node = models.ForeignKey('Node', models.DO_NOTHING, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'diagnosis'

    def __str__(self):
        return 'Diag #' + str(self.id) + ' - ' + self.code


class DiagnosisHistory(models.Model):
    id = models.IntegerField(primary_key=True)
    title = models.CharField(max_length=255, blank=True, null=True)
    date = models.DateTimeField(blank=True, null=True)
    id_user = models.TextField(blank=True, null=True)
    report = models.TextField(blank=True, null=True)
    json_report = models.TextField(blank=True, null=True)
    vin = models.CharField(max_length=20, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'diagnosis_history'

# and so on

и admin.py, где я регистрирую модели:

from django.contrib import admin

from . import models


# Do not care. Register everything
for cls in [cls for name, cls in models.__dict__.items() if isinstance(cls, type)]:
    admin.site.register(cls)

Я не хочу запускать каждую модель и вручную создавать ModelAdmin с каждым полем.


person BiAiB    schedule 16.09.2020    source источник


Ответы (1)


Это решение, которое я придумал:

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

from . import models


relationship_fields = (django_models.ManyToManyField, django_models.ForeignKey, django_models.OneToOneField)

for cls in [cls for name, cls in models.__dict__.items() if isinstance(cls, type)]:
    meta_fields = [field.name for field in cls._meta.local_fields if not isinstance(field, relationship_fields)]

    class Admin(admin.ModelAdmin):
        search_fields = meta_fields
    admin.site.register(cls, Admin)


Примечание. Регистрация всех полей не удастся, поскольку некоторые из них являются отношениями. используя cls._meta.local_fields, исключайте предполагаемые отношения, но вам также необходимо исключить такие поля, как внешние ключи, определенные в вашей модели. Таким образом, мы фильтруем с помощью isinstance(field, relationship_fields)

Примечание 2: мне, вероятно, следует использовать get_fields, поскольку local_fields кажется частным API (см. https://docs.djangoproject.com/en/3.1/ref/models/meta/)

person BiAiB    schedule 16.09.2020