Связь между Django Views и функцией Javascript - PullRequest
0 голосов
/ 08 мая 2019

В настоящее время я настраиваю свой проект Django, который является поисковой системой, и я пытался установить связь между пользовательским представлением Django и функцией Javascript, но у меня продолжали возникать проблемы, поэтому я решил перезапустить это сначало и, надеюсь, получить чью-то помощь.

У меня есть этот код Javascript

const data = []  // Not sure how to get the data from the backend??

let index = 0;
let results = [];
const randomSearchMatchPercentages = ( array ) => {
    for ( const element of array ) {
        // define a maximum and a minimum range
        const maximum = index <= 100 ? 100 - index : 0;
        const minimum = maximum > 0 ? maximum - 5 : 0;

        element.match = Math.round( Math.random() * ( maximum - minimum ) + minimum ) + "%";
        results.push( element );

        // decrease the maximum and minimum for the next iteration
        index += 5;
    }
console.log( results );
}

randomSearchMatchPercentages( data );

, который мне нужно подключить с помощью пользовательского вида, например:

def MatchingScore(request):

    return JsonResponse(output)

У меняустановил соединение и получил данные из бэкэнда для моего автозаполнения с помощью этого представления:

def autocomplete(request):
    sqs = SearchQuerySet().autocomplete(
        content_auto=request.GET.get('query',''))[:5]
    destinations = {result.destination for result in sqs}
    s = [{"value": dest, "data": dest} for dest in destinations]
    output = {'suggestions': s}
    return JsonResponse(output)

И с помощью этой функции Javascript:

$(function () {
    'use strict';

    $('#q').autocomplete({
    serviceUrl: "http://127.0.0.1:8000/search/autocomplete/",
    minChars: 2,
    dataType: 'json',
    type: 'GET',
    onSelect: function (suggestion) {
        console.log( suggestion.value + ', data :' + suggestion.data);
    }
});

});

Но я не знаю, какой кодположить внутрь моего def MatchingScore и как адаптировать код Javascript, чтобы он работал.Я предполагаю, что мне нужно будет получить данные из моей базы данных так же, как мой autocomplete View и передать их в функцию javascript.

Моя цель очень проста: генерировать случайное число от 100 до 0%и отобразить его в список HTML, который выглядит следующим образом:

<div>
{% if  page_obj.object_list %}
      <ol class="row top20">

        {% for result in page_obj.object_list %}

     <li class="list-item">
      <div class="showcase col-sm-6 col-md-4">
           <a href="{{ result.object.get_absolute_url }}">
              <h3>{{result.object.title}}</h3>
              <img src="{{ result.object.image }}" class="img-responsive">
           </a>
      </div>
     <li>

         {% endfor %}
      </ol>
</div>

{% else %}
        <p> Sorry, no result found </p>
{% endif %}

Как я могу это сделать?

РЕДАКТИРОВАТЬ:

У меня есть этоПользовательский файл forms.py, который я использую с Django-Haystack для функций поиска:

from haystack.forms import FacetedSearchForm


class FacetedProductSearchForm(FacetedSearchForm):

    def __init__(self, *args, **kwargs):
        data = dict(kwargs.get("data", []))
        self.ptag = data.get('ptags', [])
        super(FacetedProductSearchForm, self).__init__(*args, **kwargs)

    def search(self):
        sqs = super(FacetedProductSearchForm, self).search()

        if self.ptag:
            query = None
            for ptags in self.ptag:
                if query:
                    query += u' OR '
                else:
                    query = u''
                query += u'"%s"' % sqs.query.clean(ptags)
            sqs = sqs.narrow(u'ptags_exact:%s' % query)

        return sqs

Затем я передаю пользовательскую форму в свои представления с этим классом:

from haystack.generic_views import FacetedSearchView as BaseFacetedSearchView
from .forms import FacetedProductSearchForm

class FacetedSearchView(BaseFacetedSearchView):

    form_class = FacetedProductSearchForm
    facet_fields = ['ptags']
    template_name = 'search_result.html'
    paginate_by = 20
    context_object_name = 'object_list'

I 'Мы попробовали первый подход, но я не получил никаких результатов поиска, и так как у меня уже есть pagination и object_name, есть ли способ реализовать как def MatchingScore, так и def random_search_match_percentages в этом классе с помощьюсделать отступ или что-то еще, чтобы я мог вызвать match внутри этого тега шаблона?:

{% if  page_obj.object_list %}

        {% for result in page_obj.object_list %}

         {% endfor %}

{% else %}

{% endif %}

1 Ответ

0 голосов
/ 08 мая 2019

Я думаю, у вас есть два разных подхода к тому, чего вы пытаетесь достичь, если я правильно понимаю проблему.

Один из подходов: вы можете преобразовать этот код Javascript, который вы хотите запустить, в код Python (поскольку он не выполняет каких-либо определенных вещей JavaScript, таких как работа с DOM), и вызывает его из MatchingScore, передавая нужные вам данные, захватывая их, как вы делали с помощью функции autocomplete.

from django.shortcuts import render
from django.core.paginator import Paginator


def random_search_match_percentages(array):
    from random import random
    from math import floor

    index = 0
    results = []

    for element in array:
        # define a maximum and a minimum range
        maximum = 100 - index if index <= 100 else 0
        minimum = maximum - 5 if maximum > 0 else 0

        num = floor(random() * (maximum - minimum) + minimum + 0.5)
        element.match = '{}%'.format(num)  # add the match param
        results.append(element)

        # decrease the maximum and minimum for the next iteration
        index += 5

    return results


# small tip: this naming convention you are using is generally used
# for python classes, not function. Generally python developers
# write function names using snake case, like this: matching_score
def MatchingScore(request):
    some_data = MyModel.objects.all()  # just an example of grabbing data...
    paginator = Paginator(some_data, per_page=20)
    page_obj = paginator.get_page(page)

    results = random_search_match_percentages(page_obj)

    return render(request, 'my_app/my_view.html', {'results': results})

Затем вы можете получить доступ к своим данным внутри этого my_view.html точно так же, как ваш фрагмент кода шаблона Django.

Создайте файл my_view.html внутри папки шаблонов приложения, то есть: django_project/my_app/templates/my_app/my_view.html со следующим:

<div>
{% if results|length %}
  <ol class="row top20">
    {% for result in results %}
      <li class="list-item">
        <div class="showcase col-sm-6 col-md-4">
           <a href="{% url 'some-product-url' result.django_id %}">
            <h3>{{ result.title }}</h3>
              <!-- use the match param added on the
              random_search_match_percentages function -->
              <p>{{ result.match }}</p>
              <img src="{{ result.image }}" class="img-responsive">
           </a>
        </div>
      </li>
  {% endfor %}
  </ol>
{% else %}
  <p>Sorry, no result found</p>
{% endif %}
</div>

Другой подход заключается в следующем:

1) создать представление django, которое возвращает нужные вам данные JSON (например, представление autocomplete)

def matching_score_data(request):
    # grab your data...
    return JsonResponse(data)

2) затем создайте простое представление

from django.shortcuts import render


def MatchingScore(request):
    return render(request, 'my_app/my_view.html')

3) Затем поместите свой код JavaScript в `my_view.html.Для получения данных вы можете сделать AJAX-вызов, чтобы получить их.Чтобы сделать список.вам нужно будет манипулировать DOM с помощью JavaScript.

<ol class="row top20" id="my_list">
</ol>

<script>
$(function () {
    'use strict';

    const randomSearchMatchPercentages = array => {
        let index = 0;
        let results = [];

        for (const element of array) {
            // define a maximum and a minimum range
            const maximum = index <= 100 ? 100 - index : 0;
            const minimum = maximum > 0 ? maximum - 5 : 0;

            element.match = Math.round( Math.random() * ( maximum - minimum ) + minimum ) + "%";
            results.push(element);

            // decrease the maximum and minimum for the next iteration
            index += 5;
        }
        return results;
    }

    $.get("/matching_score_data", function(data) {
        // randomSearchMatchPercentages function in here...
        const results = randomSearchMatchPercentages(data);

        // now, to show the list you need to manipulate
        // the DOM appending the elements inside the
        // #my_list ol element
        for (let i = 0; i < data.length; i++) {
            $("#my_list ol").append(`
                <li class="list-item">
                    <div class="showcase col-sm-6 col-md-4">
                        <a href="${results[i].url}">
                            <h3>${results[i].title}</h3>
                            <p>${results[i].match}</p>
                            <img src="${results[i].image}" class="img-responsive">
                        </a>
                    </div>
                </li>
            `);
        }
    });
});
</script>

ИМХО: я думаю, что подход проще, потому что вы обладаете мощью механизма шаблонов django и вам не нужно манипулировать DOM с помощью javascript.Кроме того, вам нужно создать только один вид вместо двух.

Refs:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...