Home > Net >  Django ajax search button more than one data
Django ajax search button more than one data

Time:09-10

I have a django project. In this project, I made a search box with ajax, but the same data is coming more than once. Is the problem in ajax? or is the problem in django? I am not sure. Please help me.

Hey guys.I have a django project. In this project, I made a search box with ajax, but the same data is coming more than once. Is the problem in ajax? or is the problem in django? I am not sure. Please help me.

Hey guys.I have a django project. In this project, I made a search box with ajax, but the same data is coming more than once. Is the problem in ajax? or is the problem in django? I am not sure. Please help me. my html code


   enter code here

<form  method="POST">
               {% csrf_token %}
               <input type="text" name="text" placeholder="Ne Aramıştınız?"  id="searchInputChange">
               <button>Ara <i ></i></button>
           </form>

           <div >
               <div id="null-search-dietitians">
                   Aradığınız sonuç bulunamadı. Lütfen aradığınız kelimeyi gözden geçiriniz.
               </div>
               {% for posts in posts%}
               <div  data-firs-load="true">
                   <div >
                       <img src="{{posts.photo}}" alt="">
                       <a onclick="openVideoModal(event)" data-iframe-link="{{posts.video}}">
                           <i ></i>
                           <br>
                           İzle
                       </a>
                   </div>

                   <div >
                       <div >
                           <div >
                               <div >
                                   {{posts.isim}} {{posts.soyisim}}
                               </div>
                               <div >
                                   {{posts.uzmanlik}}
                                   </div>
                               <div >
                                   <i ></i>
                                   <i ></i>
                                   <i ></i>
                                   <i ></i>
                                   <i ></i>
                               </div>
                           </div>
                           <div >
                               <div >
                                   <div >
                                       Yorum Sayısı
                                   </div>
                                   <div >
                                       {{posts.yorum_sayi}}
                                   </div>
                               </div>
                               <div >
                                   <div >
                                       Danışan Sayısı
                                   </div>
                                   <div >
                                       {{posts.danisan_sayi}}
                                   </div>
                               </div>
                           </div>
                       </div>
                       <div >
                           <div >
                               <div>Uzmanlıklar :</div>
                               <div> {{posts.hizmetler}} </div>
                           </div>
                           <div >
                               <div >
                                   <div >
                                       <a href="{% url 'diyetisyen' slug=posts.slug %}">Profili İncele</a>
                                   </div>
                                   <div >
                                       <a href="{%url 'randevu' slug=posts.slug %}">Randevu Al</a>
                                   </div>
                               </div>
                           </div>
                       </div>
                   </div>
               </div>
               {% endfor %}
           </div>

my ajax code


    enter code here

const nullDietitans = document.getElementById('null-search-dietitians')
const pagination = document.querySelector('.pagination')
const dietitiansContent = document.querySelector(".all-dietitans-content")
const dietitansFirstLoad = document.querySelectorAll('.all-dietitans-content > .dietitans[data-firs-load="true"]')
const searchInputChange=document.querySelector("#searchInputChange");

searchInputChange.addEventListener('input',(e)=>{
    nullDietitans.style.display = 'none'
    let searchValue=e.target.value.trim();
    
    if(searchValue.length>=3){
        if(searchValue === ''){
            dietitansFirstLoad.forEach(element=>{
                element.style.display = 'flex'
            })
            pagination.style.display = 'flex'
            document.querySelectorAll('.all-dietitans-content > .dietitans[data-search="true"]').forEach(element=>{
                element.remove()
            })
            nullDietitans.style.display = 'none'
        }
        else{
            fetch("/getDietitians",{
                body: JSON.stringify({searchText:searchValue}),
                method: "POST",

            })
            .then((res)=>res.json())
            .then((data)=>{
                console.log(data)
                dietitansFirstLoad.forEach(element=>{
                    element.style.display = 'none'
                })
                pagination.style.display = 'none'
                if(data.length > 0){
                    $.each(data,(index,value)=>{
                        $.each(data,(index1,value1)=>{
                            
                            $(".all-dietitans-content").append(''  
                                '<div  data-search="true"><div >'  
                                '<img src="' value1.photo '" alt="">'  
                                '<a onclick="openVideoModal(event)" data-iframe-link="' value1.video '">'  
                                '<i ></i><br>İzle</a></div><div ><div ><div ><div >'  
                                value1.isim   ' '   value1.soyisim  
                                '</div><div >'  
                                value1.uzmanlik  
                                '</div><div ><i ></i><i ></i><i ></i><i ></i><i ></i></div></div><div ><div ><div >Yorum Sayısı</div><div >'  
                                value1.yorum_sayi  
                                '</div></div><div ><div >Danışan Sayısı</div><div >'  
                                value1.danisan_sayi  
                                '</div></div></div></div><div ><div ><div>Uzmanlıklar :</div><div>'  
                                value1.hizmetler  
                                '</div></div><div ><div ><div >'  
                                '<a href="/diyetisyen/' value1.slug '">Profili İncele</a>'  
                                '</div><div >'  
                                '<a href="/randevu/' value1.slug '">Randevu Al</a>'  
                                '</div></div></div></div></div></div>')
                        })
                    })
                }
                else{
                    nullDietitans.style.display = 'block'
                    document.querySelectorAll('.all-dietitans-content > .dietitans[data-search="true"]').forEach(element=>{
                        element.remove()
                    })
                }
            });
        }
    }
    else{
        dietitansFirstLoad.forEach(element=>{
            element.style.display = 'flex'
        })
        pagination.style.display = 'flex'
        document.querySelectorAll('.all-dietitans-content > .dietitans[data-search="true"]').forEach(element=>{
            element.remove()
        })
        nullDietitans.style.display = 'none'
    }

})


CodePudding user response:

It's because you're doing multiple queries and | to combine them, that's why it is returning duplicates.
instead of doing list = query1 | query2 use Q objects

@csrf_exempt
def getDietitians(request):
    from django.http import JsonResponse
    if request.method == "POST": 
        search_str=json.loads(request.body).get('searchText')

        from django.db.models import Q
        expenses = diyetisyenler.objects.filter(
            Q(isim__istartswith=search_str) | 
            Q(soyisim__istartswith=search_str) | 
            Q(uzmanlik__icontains=search_str) | 
            Q(hizmetler__icontains=search_str)
            )

        data=expenses.values()
        return JsonResponse(list(data),safe=False)

Edit

Answer: JS issue, the item list should be removed on every search


And I've worked with similar applications, so I'll drop some ideas I've done :)

Delay

It might be a good idea to add a delay, so it's not posting for every single keystroke.

Example: Searching for abc
  1. Searches for a
  2. Searches for ab
  3. Searches for abc

With a delay, I've got it at 400 milliseconds, more than likely I'll just search once for abc - unless the person types super slow

View
// global unfortunately :(
var interval = 0;
var counter = 0;

$('#inputfield').on('input', function(e) {
    if (!$(this).is(':focus')){ return; }
    var search = $(this).val().trim();

    if (search){
        clearInterval(interval);
        interval = setInterval(function() {
            counter  ;

            if (counter >= 4){ // 4 * 100 => 400 millisecond delay
                clearInterval(interval);
                counter = 0;

                searchfunction(this);
            };
        }, 100);
    }else{
        // Could clear results here
    };
};

Ping-Pong Timestamp

Larger Queries will sometimes overwrite smaller ones

Example:
  1. Send search for a (query1) [takes 15 seconds]
  2. Send search for absolutely (query2) [takes 2 seconds]
  3. query2 returns
  4. query1 returns, overwriting query2 (not good)
Solution
  1. On Javascript POST, send 'time': Date.now(), along with search
  2. In python return time with the results
    • {'list':list(data), 'time':request.POST.get('time')}
  3. On Javascript POST return, check if return is newer than rendered
    • If newer: updated results & it's time (time would be any way to store when you sent the search for the what's rendered)
    • If older: just skip the render
  • Related