回答
這將是更好的和更快,如果你只是增加一列,預先計算(memoizes)的長度文本的 。
例如
class MyModel(models.Model):
text = models.TextField()
text_len = models.PositiveIntegerField()
def save(self, *args, **kwargs):
self.text_len = len(self.text)
return super(MyModel, self).save(*args, **kwargs)
MyModel.objects.filter(text_len__gt = 10) # Here text_len is pre-calculated by us on `save`
是因爲文本字段沒有編入索引並且每次計算文本長度查詢到達數據庫的時間。 lain建議的解決方案也是這樣做的,不是嗎(儘管這個解決方案對我來說並不合適)。 – ashish
@ashish 1)是的,它是預先計算的。 2)沒有拉寧不這樣做。 – rantanplan
1)所以如果長度是預先計算,那麼爲什麼我需要另一列2)如果字符發生大於n,lain的解決方案不檢查每個表達式? – ashish
您可以使用正則表達式過濾器來搜索特定長度的文本:
MyModel.objects.filter(text__regex = r'.{10}.*')
警告:爲MySQL,最大長度爲255,否則會拋出異常:
DatabaseError: (1139, "Got error 'invalid repetition count(s)' from regexp")
作爲[文檔](https://docs.djangoproject.com/en/dev/ref/models/querysets/#regex)說:'使用原始字符串(例如,r'foo'而不是'foo')來傳遞在正則表達式語法是建議。「# –
@goliney謝謝你,你是正確的。我編輯了我的答案。 –
我在執行代碼 **後發現此異常** OperationalError:(1139,「從regexp得到錯誤'無效重複計數」)** 這是因爲大括號。 – ashish
另一種方法是:
MyModel.objects.extra(where=["CHAR_LENGTH(text) > 300"])
這可以用在文本lenght過超過255個字符。
如果你有sqlite,它是'LENGTH(..)'。 –
Django的> = 1.8可以使用Length function,這是@ Pratyush的CHAR_LENGTH()
引擎蓋爲MySQL下,或LENGTH()
其他一些數據庫:
from django.db.models.functions import Length
qs = MyModel.objects.annotate(text_len=Length('text_field_name')).filter(
text_len__gt=10)
假設我不想過濾查詢集,而是首先返回對象'text_len__gt = 10'('order_by')。任何提示? – vabada
@dabad,你可以像使用任何其他數據庫*字段*一樣使用'text_len' *註解*,所以它可以在'order_by'或'Sum'或其他任何內容中使用。按照遞減的文本長度順序排序結果並返回長度值:'MyModel.objects.annotate(text_len = Length('text_field_name'))。order_by(' - text_len')。values_list('text_len',flat = True) '。 – hobs
@guettli一個被接受的答案的問題是,原始的海報已經在2015年9月上次被看到,並且您令人欽佩的利他主義是唯一的可能性:-)我必須先編輯這個答案,然後纔可以上傳。我添加了一個類似的[Django> = 1.9](https://stackoverflow.com/a/45260608/448474),它不需要註釋,而是一個全局註冊的「Length」變換。 – hynekcer
爲Django的一個不錯的解決辦法> = 1.9可以通過註冊內置函數Length
作爲轉換查找CharField
。 (見文檔爲Length as a transform完全相同的例子)
from django.db.models import CharField
from django.db.models.functions import Length
CharField.register_lookup(Length, 'length')
result = MyModel.objects.filter(text__length__gt=10)
它可以正確處理所有的後端,通過LENGTH()
大多數後端編譯和CHAR_LENGTH()
爲MySQL。然後它自動註冊CharField的所有子類,例如爲EmailField。 TextField
必須單獨註冊。註冊名稱「長度」是安全的,因爲變換名稱永遠不會被同名的字段名稱或相關字段名稱遮蔽或遮蔽。
唯一的缺點可能是可讀性難題:「長度」從哪裏來? (查找是全球性的,但同樣可以幸運地安全地在多個模塊反覆註冊,如果可讀性是有用的,而不會在查詢運行任何可能的開銷。)
其他類似的有價值的解決方案是hobs的上面是短如果註冊計數並且不重複使用類似的查詢。
我會解決您的應用程序服務器上的問題,而不是稅收您的數據庫。你可以這樣做:
models_less_than_ten = []
mymodel = MyModel.objects.all()
for m in mymodel:
if len(m.text) > 10:
models_less_than_ten.append(m)
這對MyModel中的很多行不會很好地擴展。如果你有100,000行,那麼對數據庫執行strlen並決定不發送一行數據的話,會比嚮應用程序服務器發送大量數據以過濾掉更少。在db上完成這項工作幾乎總是比較好的,如果它太慢或徵稅,查詢可以優化。 – nevelis
- 1. Django的過濾器 - 根據過濾器
- 2. Django的過濾器
- 3. Django的過濾器
- 4. 過濾的過濾器在Django管理
- 5. 過濾器Django Queryset:ValueError
- 6. 過濾器通過在Django
- 7. django過濾器:可以過濾元組?
- 8. Django過濾器不按user_id過濾
- 9. Django的意見/過濾器
- 10. Django的過濾器對象
- 11. Django的:使用過濾器
- 12. Django的模板過濾器
- 13. Django的查詢過濾器
- 14. Django的:從過濾器
- 15. Django的帶過濾器
- 16. django過濾器的幫助
- 17. Django的過濾器「或」
- 18. django ManyToManyField的Queryset過濾器?
- 19. Django的:過濾器外鍵
- 20. Django過濾器循環或
- 21. Django objects.filter多個過濾器
- 22. Django:後續OR過濾器
- 23. Django過濾器查詢
- 24. Django - 過濾器模型
- 25. django過濾器和更新
- 26. Django管理員過濾器
- 27. Django過濾器vs排除
- 28. Django過濾器推演ManyToMany
- 29. django queryset過濾器問題
- 30. Django「評估」過濾器?
使用https://docs.djangoproject.com/en/dev/ref/models/database-functions/#django.db.models.functions.Length功能。 – guettli