Django : 'empty_form' is not used in polymorphic formsets, use 'empty_forms' instead

I am newbie at Python/Django i have been charged to migrate old project from Python 3.7 / Django 2.2.5 to the Python 3.12 and Django 5.1 but when i did this some functionality didn't work now .

For exemple before i have in the Admin interface when i click on "Add watcher" i can create watcher and in the same page choose the realted Trigger, Indicator and other staff.

But in my new version when i choose Add Watcher i have this error :

RuntimeError at /admin/watchers/watcher/add/
'empty_form' is not used in polymorphic formsets, use 'empty_forms' instead.

I am using the last version of django-polymorphic, nested-admin , I know that django-polymorphic is listed as only supporting Django versions 2.2, 3.0, 3.1, 3.2 and 4.0. It does not support Django version 5.1 , I tried the a later version using pip install git+https://github.com/jazzband/django-polymorphic.git@v4.0.0a#egg=django-polymorphic and also Django 4.x i got the same error:

from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicInlineSupportMixin
import nested_admin
from django.db import transaction
from watchers.models import *
 
class TriggerInline(nested_admin.NestedStackedPolymorphicInline):
    model = apps.get_model('triggers', 'Trigger')
    child_inlines = tuple([type(f'{subclass.__name__}Inline', (nested_admin.NestedStackedPolymorphicInline.Child,),
                                {
                                    'model': subclass,
                                    'inlines': [
                                        TriggerComponentInline] if subclass.__name__ == "CompositeTrigger" else []
                                }) for subclass in apps.get_model('triggers', 'Trigger').__subclasses__()])

#Same that TriggerInline
class IndicatorInline(nested_admin.NestedStackedPolymorphicInline)    

class WatcherChildAdmin(PolymorphicChildModelAdmin):
    base_model = Watcher
    inlines = (IndicatorInline, TriggerInline,)
    #Other infos

#Register subclass
for subclass in Watcher.__subclasses__():
    admin_class = type(f'{subclass.__name__}Admin',
                       (nested_admin.NestedPolymorphicInlineSupportMixin,WatcherChildAdmin,),
                       {
                           'base_model': subclass,
                           'exclude': ['periodicTask', ],
                       })
    admin.site.register(subclass, admin_class)


@admin.register(Watcher)
class WatcherParentAdmin(PolymorphicInlineSupportMixin, PolymorphicParentModelAdmin):
    base_model = Watcher
    child_models = tuple(Watcher.__subclasses__())
    #Other Functions

Both Trigger and Indicator have watcher in the model, example :

class Indicator(PolymorphicModel): ..... watcher = models.OneToOneField(Watcher, null=True, on_delete=models.CASCADE)

If you help me you are better than Chatgpt,DeepSeek,Mistral (they could not find solution)

Full traceback =>

Thanks

Artificial intelligence, I think, could not offer a solution because there is none.

The django-polymorphic library only supports up to version 4.0 of Django and Python up to version 3.9 according to the official documentation and there is nothing that can be done about it. There are two options: suggest leaving the project on older versions of Django and Python or replace the framework.

In the second case, you can use the built-in Django Contenttypes (GenericForeignKey) or django-model-utils (for example, InheritanceManager and, by the way, django-model-utils supports Django 3.2+ so if you take a closer look at the functionality of this framework, it might suit you.).

Unfortunately, I can't offer any other solutions.

Maybe your code could look like this (using the tools provided (must be compared with everything in your model and other code! Do not use without testing!)):

from django.contrib import admin
from model_utils.managers import InheritanceManager
#Other imports


class Watcher(models.Model):
    name = models.CharField(max_length=100)

    objects = InheritanceManager()


class Trigger(models.Model):
    watcher = models.ForeignKey(Watcher, null=True, on_delete=models.CASCADE)


class TriggerInline(nested_admin.NestedStackedInline):
    model = Trigger
    
    child_inlines = tuple([
        type(f'{subclass.__name__}Inline', (nested_admin.NestedStackedInline.Child,),
             {
                 'model': subclass,
                 'inlines': [TriggerComponentInline] if subclass.__name__ == "CompositeTrigger" else []
             }) for subclass in Trigger.__subclasses__()
    ])


class IndicatorInline(nested_admin.NestedStackedInline):
    model = apps.get_model('indicators', 'Indicator')


class WatcherChildAdmin(admin.TabularInline):
    model = Watcher
    inlines = (IndicatorInline, TriggerInline,)


@admin.register(Watcher)
class WatcherParentAdmin(admin.ModelAdmin):
    inlines = (IndicatorInline, TriggerInline)

However, you can try. And I really hope that my answer helped at least a little.

Вернуться на верх