【问题标题】:Using Javascript to implement Live Django Search使用 Javascript 实现 Live Django Search
【发布时间】:2021-04-08 16:26:00
【问题描述】:

我正在使用 Javascript 向我的电子商务项目添加搜索功能,我遵循了一个教程,该教程解释了在搜索栏中编写标题时,只会出现具有相同字母的项目。在我的项目中,它适用于基本 HTML,但我试图让它更复杂一点,包括包含价格等一些细节的完整卡片,而不仅仅是标题。

这里是model.py

class Item(models.Model):
    title = models.CharField(max_length=100)
    image = models.ImageField(blank=False, upload_to=upload_design_to)
    price = models.DecimalField(decimal_places=2, max_digits=100)
    discount_price = models.DecimalField(decimal_places=2, max_digits=100, blank=True, null=True)
    timestamp = models.DateTimeField(default=timezone.now)

这里是views.py

class ItemListView(ListView):
    model = Item
    paginate_by = 12
    template_name = "store/product_list.html"
    ordering = ['-timestamp']

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["qs_json"] = json.dumps(list(Item.objects.values()),cls=DjangoJSONEncoder)
        return context

这里是scripts.py

<script>
    const data = '{{qs_json}}'

    const rdata = JSON.parse(data.replace(/&quot;/g, '"'))
    console.log(rdata)

    const input = document.getElementById('search_here')
    console.log(input)

    let filteredArr = []

    input.addEventListener('keyup', (e)=>{
        box.innerHTML = ""
        filteredArr = rdata.filter(store=> store['title'].includes(e.target.value))
        console.log(filteredArr)
        if (filteredArr.length > 0){
            filteredArr.map(store=>{
                box.innerHTML += `<b>${store['title']}</b><br>`
            })
        } else {
            box.innerHTML = "<b>No results found...</b>"
        }
    })
</script>

这是模板.html

<input id="search_here" class="mb-2 form-control" placeholder="Type to search...">

<!--Card-->
<div id="box" class='row card-group'>
{% for item in object_list %}
  <div class="col-4 mb-3">
    <div class="card h-100">
        <a href="{{item.get_absolute_url}}">
      <embed src="{{ item.image.url }}" class="card-img-top" alt="..."/>
        </a>
      <div class="card-body">
        <h5 class="card-title">{{ item.title }}</h5>
          <p class="card-text">
        {% if item.description %}
            {{ item.description }}
        {% endif %}
        </p>
      </div>
      <div class="card-footer">
        <small class="text-muted">{{ item.timestamp }}</small>
      </div>
    </div>
  </div>
{% endfor %}
</div>
<!--Card-->

我的问题:如何在脚本中将简单的&lt;b&gt;${store['title']}&lt;/b&gt;&lt;br&gt; 替换为带有所有相关信息的整个卡片 div?

如果需要更多信息或说明,请告诉我

  <div class="col-4 mb-3">
    <div class="card h-100">
        <a href="{{item.get_absolute_url}}">
      <embed src="{{ item.image.url }}" class="card-img-top" alt="..."/>
        </a>
      <div class="card-body">
        <h5 class="card-title">{{ item.title }}</h5>
          <p class="card-text">
        {% if item.description %}
            {{ item.description }}
        {% endif %}
        </p>
      </div>
      <div class="card-footer">
        <small class="text-muted">{{ item.timestamp }}</small>
      </div>
    </div>
  </div>

【问题讨论】:

    标签: javascript python html json


    【解决方案1】:
    from django.db.models import Q
    
    name = request.POST['name']
    price = request.POST['price']
    Item.objects.filter(Q(title __icontains=name) | Q(price __icontains=price))
    

    试试这个

    【讨论】:

    • 我正在寻找在 Javascipt Innerbox 中容纳 Django 模板的解决方案。我认为这需要重定向到另一个页面
    • 请提供一些例子。如果您想在不刷新页面的情况下从 Django 获取新数据?如果是:可以使用 Ajax 请求
    • 在我的帖子中,我已经实现了搜索选项,但我只能从搜索中看到包含相似字母的标题,这是因为在脚本box.innerHTML +=${store[ '标题']}
      ``.我的目标是让整张卡片出现。不仅仅是标题
    【解决方案2】:

    您的 template.html 页面已经包含使用 for-loop 生成的所有 html,因此您不需要再次生成它们。相反,当用户键入时,您可以遍历所有 div 并检查 card-title div 是否具有 @987654324 @ 如果它只是显示该 div 或者隐藏它。

    演示代码

    const input = document.getElementById('search_here')
    input.addEventListener('keyup', (e) => {
      var inputs = e.target.value.toLowerCase(); //do lowercase
      //loop through outer div and hide it
      document.querySelectorAll('.outers').forEach(function(el) {
        el.style.display = 'none';
      });
      //loop through outer ->card-title
      document.querySelectorAll('.outers .card-title').forEach(function(el) {
        //compare 
        if (el.textContent.toLowerCase().indexOf(inputs) > -1) {
          el.closest('.outers').style.display = "block"; //if match show that div
        }
      })
    })
    .outers {
      border: 1px solid blue;
      width: 150px;
      height: 150px;
      margin-bottom: 5px
    }
    <input id="search_here" class="mb-2 form-control" placeholder="Type to search...">
    <div id="box" class='row card-group'>
      <!--just added one extra class-->
      <div class="col-4 mb-3 outers">
        <div class="card h-100">
          <a href="{{item.get_absolute_url}}">
            <img src="{{ item.image.url }}" class="card-img-top" alt="..." />
          </a>
          <div class="card-body">
            <h5 class="card-title">Somethings</h5>
            <p class="card-text">
              some things ...
            </p>
          </div>
          <div class="card-footer">
            <small class="text-muted">12:30:00</small>
          </div>
        </div>
      </div>
      <div class="col-4 mb-3 outers">
        <div class="card h-100">
          <a href="{{item.get_absolute_url}}">
            <img src="{{ item.image.url }}" class="card-img-top" alt="..." />
          </a>
          <div class="card-body">
            <h5 class="card-title">Abc</h5>
            <p class="card-text">
              some things ...
            </p>
          </div>
          <div class="card-footer">
            <small class="text-muted">12:30:00</small>
          </div>
        </div>
      </div>
      <div class="col-4 mb-3 outers">
        <div class="card h-100">
          <a href="{{item.get_absolute_url}}">
            <img src="{{ item.image.url }}" class="card-img-top" alt="..." />
          </a>
          <div class="card-body">
            <h5 class="card-title">def</h5>
            <p class="card-text">
              some things ...
            </p>
          </div>
          <div class="card-footer">
            <small class="text-muted">12:30:00</small>
          </div>
        </div>
      </div>
    </div>

    【讨论】:

      【解决方案3】:

      我认为您可以通过以下代码更改脚本。

      
      const data = '{{qs_json}}'
      
      const rdata = JSON.parse(data.replace(/&quot;/g, '"'))
      console.log(rdata)
      
      const input = document.getElementById('search_here')
      console.log(input)
      
      let filteredArr = []
      
      input.addEventListener('keyup', (e) => {
          box.innerHTML = ""
          filteredArr = rdata.filter(store => store['title'].includes(e.target.value))
          console.log(filteredArr)
          if (filteredArr.length > 0) {
              filteredArr.map(store => {
                  box.innerHTML += `
                  <div class="col-4 mb-3">
                      <div class="card h-100">
                          <a href="${store['get_absolute_url']}">
                              <embed src="${store['image']['url']}" class="card-img-top" alt="..."/>
                          </a>
                          <div class="card-body">
                              <h5 class="card-title">${store['title']}</h5>
                              <p class="card-text">
                                  ${store['description'] ?? ''}
                              </p>
                          </div>
                          <div class="card-footer">
                              <small class="text-muted">${store['timestamp']}</small>
                          </div>
                      </div>
                  </div>`;
              })
          } else {
              box.innerHTML = "<b>No results found...</b>"
          }
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-27
        • 1970-01-01
        • 2011-10-22
        • 2021-06-24
        • 2017-03-22
        • 1970-01-01
        • 1970-01-01
        • 2019-06-07
        相关资源
        最近更新 更多