I have a model like so:
class Model(...):
code = models.CharField(...)
My model table is populated like so:
ID | CODE
-----|------------
1 | c-AB-xyz
2 | c-AC-edf
3 | c-BB-mng
4 | c-BC-lmp
5 | c-CB-qrs
6 | c-CC-tuv
I want to filter for instances based off what their code
string starts with. I also want to specifiy a start and stop.
For example, how can I filter instances that have a starting code
value between c-BB
and c-CB
?
Something like:
Model.objects.filter(
code__startswith__between = ['c-BB', 'c-CB']
)
Which should return instances 3, 4, and 5.
CodePudding user response:
First, please try with:
objs = Model.objects.filter(code__startswith__range=(rangeStart, rangeStop))
If this does not work as expected for you use the following function to filter out model items:
def string_range_filter(objs, range_start="c-BB", range_stop="c-CB"):
match = []
# find minimum length of range_start and range_stop
min_len = min(len(range_start), len(range_stop))
for item in objs:
chars_to_compare = item.code[:min_len]
if range_start[:min_len] <= chars_to_compare <= range_stop[:min_len]:
match.append(item)
return match
objects = Model.objects.all()
matches = string_range_filter(objs=objects)
CodePudding user response:
This might be easiest to do with regex:
Model.objects.filter(
code__regex=r'^c-[BC]B.*$'
)
This doesn't quite do exactly what you're asking, but it has the advantage of delegating the work to the database engine. You could then filter the resulting QuerySet, knowing that you have at least all the results that you want, if not a couple extra.