Django startswith on fields

In SQL terms, what you want to achieve reads like ('12345' is the postcode you are searching for):

SELECT *
FROM address
WHERE '12345' LIKE postcode_prefix||'%'

This is not really a standard query and I do not see any possibility to achieve this in Django using only get()/filter().

However, Django offers a way to provide additional SQL clauses with extra():

postcode = '12345'
Address.objects.extra(where=["%s LIKE postcode_prefix||'%%'"], params=[postcode])

Please see the Django documentation on extra() for further reference. Also note that the extra contains pure SQL, so you need to make sure that the clause is valid for your database.

Hope this works for you.


Edit: This does not answer the original question but how to word a query the other way around.

I think what you are trying to do with your "something like" line is properly written as this:

Address.objects.filter(postcode__startswith=postcode_prefix)

Bit of a mouthful but you can do this by annotating your search value and then filtering against it. All happens pretty quickly in-database.

from django.db.models import Value as V, F, CharField

Address.objects.exclude(
    postcode_prefix=''
).annotate(
    postcode=Value('12345', output_field=CharField())
).filter(
    postcode__startswith=F('postcode_prefix')
)

The exclude is only necessary if postcode_prefix can be empty. This would result in an SQL like '%', which would match every postcode.

I'm sure you could do this via a nice templated function these days too... But this is clean enough for me.