我正在使用django的標準用戶模型。關鍵字在Django的幾個字段中搜索
我想通過名字和姓氏搜索用戶。所以我有一個免費的文本搜索和使用icontains我正在尋找該文本。但是,我希望用戶可以搜索「John A」,然後檢索所有的用戶,他們的名字+姓氏包含「John A」,但是,因爲我正在分別使用名字和姓氏的圖標,它不起作用。 「約翰」一個人會工作。但只要我涉及這兩個領域,它不(這是有道理的)
任何簡單的解決方案呢?
我正在使用django的標準用戶模型。關鍵字在Django的幾個字段中搜索
我想通過名字和姓氏搜索用戶。所以我有一個免費的文本搜索和使用icontains我正在尋找該文本。但是,我希望用戶可以搜索「John A」,然後檢索所有的用戶,他們的名字+姓氏包含「John A」,但是,因爲我正在分別使用名字和姓氏的圖標,它不起作用。 「約翰」一個人會工作。但只要我涉及這兩個領域,它不(這是有道理的)
任何簡單的解決方案呢?
使用Q對象創建查詢,並使用|
作爲OR,使用&
作爲AND。
>>> from django.db.models import Q
>>> qs = Q(first_name__icontains='John A') | Q(last_name__icontains='John A')
>>> User.objects.filter(qs)
閱讀更多關於它here
附:您還可以使用|
和&
參加定期查詢集
User.objects.filter(...) | User.objects.filter(...)
但我想用品質的對象僅僅是整潔多個字段
編輯
與參數您的評論會在何時,所有你想要做的是這樣的:
>>> query = 'John A'
>>> fn, ln = query.split()
>>> User.objects.filter(first_name=fn, last_name=ln)
對於複雜情況,您可能需要檢查名字和姓氏。第二個通常是中間名或其他部分,所以icontain會抓住它。所以像這樣:
>>> query = 'Jon Van Mendrik'
>>> fn, ln = [i[0], i[-1] for i in query.split()] #take the first and last
>>> print fn, ln
"Jon Mendrik"
>>> qs = Q(first_name__icontains=fn, last_name__icontains=ln)
>>> qs = qs | Q(first_name__icontains=ln, last_name__icontains=fn)
>>> User.objects.filter(qs).distinct()
這不是很漂亮,但可能適用於大多數情況下,包括最先輸入姓氏等等。只要確保你明白我在這裏所做的並不僅僅是一味地把它複製到你的項目 -
|
你可能會添加更多的邏輯。例如,'John A' - 姓氏顯然是首字母縮寫,而不是全名,而第一個是全名。你可以實現一些邏輯來處理這個問題,並相應地構建查詢集(contains
比startswith
更昂貴,或者簡單的比較)。使用Q對象可以使這一點變得簡單。玩弄它,你會得到它的掛鉤
這不會工作......沒有first_name和last_name包含「約翰A」... first_name包含「約翰」和last_name包含「A」這是我的問題... –
好吧,所以你想要一些更簡單的東西。請參閱編輯 – yuvi
剛剛從評論中獲得了該建議。我很擔心像「Jon Van Mendrik」這樣的名字:)或者如果有人寫「John A」或「John」 –
我建議你使用natural_key。在用戶模型中,添加類似:
def natural_key(self):
return (self.first_name, self.last_name)
結果:
users = User.objects.filter()
for user in users:
print(user.natural_key)
然後,您可以在自然鍵過濾。
希望它有幫助。
如何使用自然鍵過濾? User.objects.filters(natural_key__icontains ==關鍵字)?我不認爲這將工作... –
我投下,因爲自然鍵會在用戶模型的方法不會在數據庫中存在過濾,所以它顯然不回答問題,並不會工作。 – user2734679
所以。你是否想把'John A'分解爲'first_name ='John''和'last_name ='A''? – karthikr
是的。這就是用戶模型的實現方式。 first_name和lat_name被分割。你建議我在後端拆分空間嗎?我計劃在兩個領域進行更多的搜索。如搜索時合併名字和上次。但你建議相反,它可以工作:) –