Open roniemartinez opened 3 weeks ago
@roniemartinez Could you put together a proof-of-concept showing what you mean here, perhaps with tests showing different examples? Thanks.
If you have a field in your model like:
code_full = models.GeneratedField(
expression=If(Q(code_number__isnull=True), Value(None), Concat("code_prefix", "code_number")),
db_persist=True,
output_field=models.CharField(blank=True, null=True, max_length=15),
)
Then an error like @roniemartinez posted above will be raised.
This can be fixed with overriding filter_for_field()
(note the # Handle GeneratedFields
block):
@classmethod
def filter_for_field(cls, field, field_name, lookup_expr=None):
if lookup_expr is None:
lookup_expr = settings.DEFAULT_LOOKUP_EXPR
# Handle GeneratedFields
if isinstance(field, GeneratedField):
new_field = field.output_field
new_field.model = field.model
field = new_field
field, lookup_type = resolve_field(field, lookup_expr)
default = {
"field_name": field_name,
"lookup_expr": lookup_expr,
}
filter_class, params = cls.filter_for_lookup(field, lookup_type)
default.update(params)
assert filter_class is not None, (
"%s resolved field '%s' with '%s' lookup to an unrecognized field "
"type %s. Try adding an override to 'Meta.filter_overrides'. See: "
"https://django-filter.readthedocs.io/en/main/ref/filterset.html"
"#customise-filter-generation-with-filter-overrides"
) % (cls.__name__, field_name, lookup_expr, field.__class__.__name__)
return filter_class(**default)
It might not be the perfect fix, but it's worked well for me in my testing.
So there's two parts to this.
The is the error. That should be addressed by #1675, which will enable skipping unknown fields — if you haven't used filter_overrides.
The second is the generated field handling itself:
# Handle GeneratedFields
if isinstance(field, GeneratedField):
new_field = field.output_field
new_field.model = field.model
field = new_field
Is it as simple as that? Can we add built-in support?
Disclaimer: I haven't used GeneratedField yet, so haven't looked into what works and doesn't here at all.
Is it as simple as that? Can we add built-in support?
Built-in support would be great! I can't find a problem with this solution so far, and it's been deployed to production today, so 🤞
I'll let you know if we find any issues, but I think this is all that's needed.
OK, but the correct place to add this would be to the FILTER_FOR_DBFIELD_DEFAULTS
, probably with a specific Filter subclass.
If someone wants to take that on as an addition (with docs and tests) that would be very welcome.
I've got this error which is caused by using a GeneratedField. Before migrating to GeneratedField, we used to use a migration script to create the generated field and django-filter has no issue with it.
I think it should be possible to know what filter to use since
GeneratedField
has anoutput_field
.