django同時查詢兩張表的數據,合併檢索對象返回

原始需求:mysql

  一、一篇文章內容分N個版塊,每篇文章的版塊數量不一樣。sql

       二、有個文章搜索功能,須要同時搜索標題和內容。django

實現思路:json

  一、因爲每篇文章的內容版塊數量不一樣,所以將每一個文章的標題和內容分開存入2張表中。函數

 

模型:

#標題和屬性模型
class ArticleInfoModel(models.Model):
    title = models.CharField(max_length=200)
    summary = models.TextField(null=True) 
    author = models.ForeignKey(User, null=True) 
    create_time = models.DateTimeField(null=True) 

#文章內容模型
class ArticleContentModel(models.Model):
    article = models.ForeignKey('ArticleInfoModel') 
    content = models.TextField()
    section = models.ForeignKey('ArticleContentSectionModel')
    create_time = models.DateTimeField(null=True) 

 

邏輯實現:spa

    

def search_article(request,page=1,category_id=0):
    try:
        currentPage = int(page)
        categoryId = int(category_id)
    except:
        pass

    if request.method == 'GET':
        return json_result(message=u'搜索文章頁面!')
    else:
        searchWord = request.POST.get('search_word',None)

        if searchWord:
            try:
                searchWord = str(searchWord).replace(' ','')
            except:pass

            numPage = int(configs.PC_FRONT_NUM_PAGE)
            start = (currentPage - 1) * numPage
            end = start + numPage

            if categoryId:
                methodCategoryModel = CategoryModel.objects.filter(pk=categoryId, is_active=1).first()
                if methodCategoryModel:
                    # 先過濾出符合條件的文章信息,而後在這些文章中檢索出和關鍵詞相匹配的文章
                    indexModel = ArticleInfoModel.objects.filter(status__in=[1,2,3],category=methodCategoryModel).all()
                else:
                    return json_params_error(message=u'你嘗試查看一個不存在的分類下的文章!')
            else:
                indexModel = MethodArticleInfoModel.objects.filter(status__in=[1,2,3]).all()

            # 開始檢索文章標題模型
            infoModel = indexModel.filter(Q(title__icontains=searchWord) | Q(summary__icontains=searchWord)).all()

            # 再跨表檢索文章內容模型中和關鍵詞相匹配的文章內容,而且對article去重
            contentModel = ArticleInfoModel.objects.filter(methodarticlecontentmodel__content__icontains=searchWord).distinct()
            # 因爲內容只進行關鍵詞檢索,沒有對文章其餘條件進行過濾,所以須要再次計算檢索出的內容和其餘條件的交集
            tmp_content_list = set()
            if contentModel:
                content_list = set(contentModel)
                index_list = set(indexModel)
                tmp_content_list = content_list.intersection(index_list)  #求內容模型和索引模型的交集

            # 最後將符合條件的文章標題模型和文章內容模型合併返回
            info_list = set()
            if infoModel:
                info_list = set(infoModel)

            # 在從文章標題模型中查找出最終彙總的模型返回
            articleModel = info_list.union(tmp_content_list)

        else:
            return json_params_error(message=u'請輸入要搜索的關鍵詞!')

    if len(articleModel) > 0:
       ...
      正常操做數據模型
    ...
else: return json_params_error(message=u'暫無相關文章!')

這麼作的原因:code

  一、在django 1.10版本中,不支持在一個過濾條件中同時檢索兩張表,所以只能一張一張查詢。blog

            好比:             索引

indexModel = ArticleInfoModel.objects.filter(
    Q(title__icontains=searchWords)|
    Q(summary__icontains=searchWords)|
    Q(articlecontentmodel__content__icontains=searchWords) #這是ArticleContentModel 模型    
    status__in=[1,2,3],
    category=methodCategoryModel).all()

   在官方文檔中提到,模型能夠進行關聯查詢,若是沒有關聯關係的模型能夠才用:模型名字小寫__字段名字 來進行查詢,文檔

    按照官方給的例子,單條過濾語句這樣寫沒有任何問題,可是若是把這種跨表查詢的語句和當前模型中須要過濾的條件寫在一個過濾語句中進行查詢,就拿不到想要的結果。

           所以,就才用上面的方式,先過濾A表中的數據,而後跨表過濾B表中的數據。

           之因此跨表過濾B表數據,是由於最終要將A,B表過濾的數據進行彙總。

           因爲在1.10之前版本中模型還不支持union()、intersection()這種交集、並集函數,這是在1.11版本中出的,mysql也不支持這種運算方式。

           因此將A表中符合條件的模型集轉換成set()類型,將B表中符合條件的模型集轉換成set()類型,並計算出交集。

   至此就能夠實現同時檢索兩張表的問題。

相關文章
相關標籤/搜索