Closed star2000 closed 1 year ago
Hey @star2000 ,
The ideas in here are interesting! Support for both "OR" and "NOT" are totally issues that I want to solve (I also miss having those in my projects).
We had a discussion about that on discord the order day, and Colin (don't know his github handler) shared his custom implementation as well: https://discord.com/channels/689806334337482765/689861980776955948/1126205282440204378
If I understood your solution correctly, it expects a field called OR
to apply with a |
to the rest of the filters. You didn't give any example on how the user would define that, but I imagine it would be very similar to Colin's idea of typing it as Self
.
One interesting thing he proposed is to add flag to the filters
function which would allows users to opt in to this feature, and we could inject the or
and and
fields and their resolvers.
Regarding the "NOT", I like this! I was previously wondering about a similar solution (not to say identical =P) or exposing an extra exclude
of the same type as the filters, but I don't think it would work very well when doing complex and
/or
stuff, so probably your implementation is the way to go here.
@bellini666 Regarding the definition of OR , I just do. But I think it's best to integrate this OR directly. e.g.
import strawberry_django
@strawberry_django.filter(m.Group, lookups=True)
class GroupFilter:
permissions: 'PermissionFilter | None'
name: auto
id: auto
user: 'UserFilter | None'
OR: 'GroupFilter | None'
I saw this message. https://discord.com/channels/689806334337482765/689861980776955948/1129431715752976425
Regarding the problem of a && (b || c)
, although it can be transformed into an equivalent (a && b) || (a && c)
, the behavior of repeatedly entering the condition a
is not elegant after all. So it's better to add an AND
field.
if field_name in ('AND', 'OR'):
(
subfield_filter_kwargs,
subfield_filter_methods,
) = build_filter_kwargs(field_value, path)
if field_name == 'AND':
filter_kwargs &= subfield_filter_kwargs
else:
filter_kwargs |= subfield_filter_kwargs
from typing import Self
import strawberry_django
@strawberry_django.filter(m.Group, lookups=True)
class GroupFilter:
permissions: 'PermissionFilter | None'
name: auto
id: auto
user: 'UserFilter | None'
AND: 'Self | None'
OR: 'Self | None'
query onlyOR {
Groups(
filters: {
name: {startsWith: "a"},
id: {range: [1, 2]},
OR: {
name: {startsWith: "a"},
id: {range: [3, 4]}
}
}
) {
id
}
}
query useAND {
Groups(
filters: {
name: {startsWith: "a"},
AND: {
id: {range: [1, 2]},
OR: {
id: {range: [3, 4]}
}
}
}
) {
id
}
}
@star2000 nice!
I would just call those and
and or
in the schema though. Also, maybe "injecting" those fields at the filter would make sense so that the user doesn't have to define an and
/or
by himself.
@bellini666 How to implement the filter injection attribute you mentioned, is there a code example?
@bellini666 How to implement the filter injection attribute you mentioned, is there a code example?
Probably something similar to how this PR implemented fields
/exclude
.
Inside _process_type, if the type is a filter you can inject the annotations and also set setattr(cls, "<attr>", UNSET)
@bellini666 How to implement the filter injection attribute you mentioned, is there a code example?
Probably something similar to how this PR implemented
fields
/exclude
.Inside _process_type, if the type is a filter you can inject the annotations and also set
setattr(cls, "<attr>", UNSET)
I tried it and it was successful. I just need to add this code after checking __annotations__ in _process_type
.
if is_filter:
cls.__annotations__.update({
'AND': Optional[Self],
'OR': Optional[Self],
})
There is no need to set a default value, because here is set. https://github.com/strawberry-graphql/strawberry-graphql-django/blob/5e146adb5bab1ef1ddd87ab07465d20c1e8e422b/strawberry_django/type.py#L173
Feature Request Type
Description
Because there may be bugs, or it can be solved more elegantly, so I post here for discussion.
Here is how I do it.
Where apply_filters only needs to remove the two asterisks.
Upvote & Fund