Problem
Whenever there are abstract models in a project, typomatic breaks. This is a bug. There should either be an interface generated, or it should be skipped. It should not break the program...
/python3.13/site-packages/rest_framework/serializers.py", line 1065, in get_fields
raise ValueError(
'Cannot use ModelSerializer with Abstract Models.'
)
ValueError: Cannot use ModelSerializer with Abstract Models.
Solution By Skipping
We can just check the model for which the interface is to be generated if modelName.__meta__.abstract == True and that can allow for skipping.
Solution To Make It Work With Abstract Classes
Seemingly, though I have not looked at the code, it seems the issue is that typomatic is instantiating the class to get its fields and it fails because the class is abstract. Here's an LLM output on how to get the fields of an abstract class including all its superclasses
from django.db import models
class BaseAbstract(models.Model):
base_field = models.IntegerField()
class Meta:
abstract = True
class AnotherBaseAbstract(models.Model):
another_base_field = models.CharField(max_length=100)
class Meta:
abstract = True
class MyAbstract(BaseAbstract, AnotherBaseAbstract):
my_field = models.CharField(max_length=50)
class Meta:
abstract = True
def get_abstract_model_fields(model_class):
"""
Gets all fields of an abstract Django model class, including inherited fields.
"""
fields = []
for base in model_class.__bases__:
if issubclass(base, models.Model) and base._meta.abstract:
fields.extend(get_abstract_model_fields(base)) #recursion to get fields of base classes
fields.extend(model_class._meta.fields)
return fields
def is_model_abstract(model_class):
return model_class._meta.abstract
# Example usage:
if is_model_abstract(MyAbstract):
fields = get_abstract_model_fields(MyAbstract)
for field in fields:
print(field.name, field.__class__.__name__)
# Example of a concrete class inheriting from MyAbstract
class ConcreteModel(MyAbstract):
concrete_field = models.BooleanField()
if is_model_abstract(ConcreteModel):
print("Concrete model should not be abstract")
else:
fields = get_abstract_model_fields(ConcreteModel)
print("\nFields of concrete class, before inheritance:")
for field in fields:
print(field.name, field.__class__.__name__)
print("\nFields of concrete class, after inheritance:")
for field in ConcreteModel._meta.fields:
print(field.name, field.__class__.__name__)
So get_abstract_model_fields should be used instead of the current:
django_typomatic/__init__.py", line 547, in __get_ts_interface
fields = instance.get_fields().items()
~~~~~~~~~~~~~~~~~~~^^
The problem is the instantiation of the abstract class in the line above.
Problem
Whenever there are abstract models in a project, typomatic breaks. This is a bug. There should either be an interface generated, or it should be skipped. It should not break the program...
Solution By Skipping
We can just check the model for which the interface is to be generated if
modelName.__meta__.abstract == Trueand that can allow for skipping.Solution To Make It Work With Abstract Classes
Seemingly, though I have not looked at the code, it seems the issue is that typomatic is instantiating the class to get its fields and it fails because the class is abstract. Here's an LLM output on how to get the fields of an abstract class including all its superclasses
So
get_abstract_model_fieldsshould be used instead of the current:The problem is the instantiation of the abstract class in the line above.