34

let's say that I have an Address model with a postcode field. I can lookup addresses with postcode starting with "123" with this line:

Address.objects.filter(postcode__startswith="123")

Now, I need to do this search the "other way around". I have an Address model with a postcode_prefix field, and I need to retrieve all the addresses for which postcode_prefix is a prefix of a given code, like "12345". So if in my db I had 2 addresses with postcode_prefix = "123" and "234", only the first one would be returned.

Something like:

Address.objects.filter("12345".startswith(postcode_prefix)) 

The problem is that this doesn't work. The only solution I can come up with is to perform a filter on the first char, like:

Address.objects.filter(postcode_prefix__startswith="12345"[0])

and then, when I get the results, make a list comprehension that filters them properly, like this:

results = [r for r in results if "12345".startswith(r.postcode_prefix)]

Is there a better way to do it in django?

4

6 に答える 6

44

編集:これは元の質問には答えませんが、クエリを逆に表現する方法です。

「何かのような」行で何をしようとしているのかは、次のように適切に書かれていると思います。

Address.objects.filter(postcode__startswith=postcode_prefix)
于 2012-08-10T15:59:46.903 に答える
12

SQL 用語では、達成したいことは次のようになります (「12345」は検索している郵便番号です)。

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

これは実際には標準的なクエリではなく、get()/filter() のみを使用して Django でこれを達成する可能性はありません。

ただし、Django は追加の SQL 句を提供する方法を提供していますextra()

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

詳細については、 extra() に関する Django ドキュメントを参照してください。また、エクストラには純粋な SQL が含まれているため、句がデータベースに対して有効であることを確認する必要があることに注意してください。

これがうまくいくことを願っています。

于 2012-08-10T16:53:03.397 に答える
1

可能な代替案。(実行時に、2番目のパラメーターとして列を使用して、受け入れられたソリューションとどのように比較されるかわかりません)

q=reduce(lambda a,b:a|b, [Q(postcode__startswith=postcode[:i+1]) for i in range(len(postcode))])

したがって、すべてのプレフィックスを生成するか、それらをまとめて...

于 2014-11-08T18:50:50.733 に答える