как иметь единый поисковый API с использованием параметров пути (форма не используется)

Я использовал это представление для поиска word как:

db относится к соединению монго (только для ссылки)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/words-<word>', methods=['GET', 'POST'])
def wordsearch(word):
    collection_name=word[0].lower()+'_collection'
    words=db[collection_name]
    data=words.find({'word':word})
    return render_template('wordsearch.html',data=data)

В шаблоне index.html я делал это, чтобы сопоставить этот URL-адрес выше:

    <script type="text/javascript">
        $(document).ready(function(){
         $('#submit').on('click', function() {
              var wordvalue = $("#word").val();  //getting word from element ID 
              window.location.href ="/"+"words-"+wordvalue; //match the URL in view
              })
         });
    </script>

Можно ли это сделать более динамично? Я имею в виду, что это работает только для word, а не для других вариантов выбора или комбинации вариантов, как показано ниже:

Ввод поиска выглядит так:

word length: ()
word type  : ()
word       : ()
         submit

Теперь API, который у меня есть, соответствует только в том случае, если я отправляю слово, но как я могу написать один API, чтобы он соответствовал всем возможным комбинациям, таким как слово length + word type, word + word type (запросы, которые я бы определил самостоятельно)

Что я пробовал:

@app.route('/<n>-letter-words', methods=['GET', 'POST'])
@app.route('/words-<word>', methods=['GET', 'POST'])
def wordsearch(word=None,n=None):
    if word:
        collection_name=word[0].lower()+'_collection'
        words=db[collection_name]
        data=words.find({'word':word})
        return render_template('wordsearch.html',data=data)

    data = 'you are searching with' + n + 'words'
    return render_template('lettersearch.html', data=data)

а в шаблонах scriptas:

    <script type="text/javascript">
        $(document).ready(function(){
         $('#submit').on('click', function() {
              var lettervalue = $("#wordlength").val();
              var wordvalue = $("#word").val();
              if (lettervalue==''){
                    window.location.href ="/"+"words-"+wordvalue;
               }
               else{
                window.location.href ="/"+lettervalue+"-letter-words";
               }
              })
         });
    </script>

Но смущает, если есть комбинация, например, 6-letter-words-of-verbs глагол здесь word type

Кроме того, как сопоставить тот же URL-адрес для этих комбинаций из шаблона, как я делал с JQuery, используемым в script выше?

Это правильный путь? , я думаю, писать все возможные маршруты в представлениях и сопоставлять их из шаблона с условиями в Jquery - плохая идея,

любые справочные / направляющие ссылки приветствуются, TIA


person Codenewbie    schedule 31.12.2019    source источник
comment
Такой подход может быть… опрометчивым. Является ли /foo+bar и /bar+foo одним и тем же ресурсом? О: нет. Будут ли они давать такие же эффективные результаты? Зависит от используемой поисковой системы, но URI должен быть уникальным. Является ли /search?foo+bar и /search?bar+foo одним и тем же ресурсом? О: да. Оба являются поисковым ресурсом, просто предоставлены разные строки запроса. То, что она называется строкой «запроса», должно быть убедительным намеком на предполагаемую цель. Отредактировано для добавления: обратите внимание, что при построении строки запроса не нужно использовать форму. Формы просто облегчают задачу, но ограничивают вас key=value.   -  person amcgregor    schedule 01.01.2020
comment
Ах, и очень краткое продолжение; Желание избегать (а не использовать/эксплуатировать) стандартное поведение браузера часто не является хорошим признаком с точки зрения вникания в то, как должна работать сеть (помимо HTTP). Никогда не забывайте, что такое MVC разделение здесь.   -  person amcgregor    schedule 01.01.2020
comment
@amcgregor абсолютно имеет смысл, поэтому всегда рекомендуется использовать на основе /search?bar+foo, чтобы я мог избежать любых jquery, это правильно или я неправильно понял?   -  person Codenewbie    schedule 01.01.2020
comment
@amcgregor извините, я вообще не смог получить вторую точку   -  person Codenewbie    schedule 01.01.2020
comment
Вы может всегда избегать jQuery. Хотя мне очень не нравится ES5, ES6, ну, прекрасен. И на несколько порядков быстрее. Суть в том, чтобы следовать назначению определения URI и не отказываться от автоматических функций. предоставляется браузером.   -  person amcgregor    schedule 01.01.2020


Ответы (2)


На основании моей рекомендации, предложенной в комментарии, не использовать noreferrer">игнорировать поведение клиентского браузера и следовать намерению определения URI (где /foo+bar и /bar+foo не должны представлять один и тот же ресурс), следующее - это все, что вам на самом деле требуется, и автоматически обрабатывает URI-кодирование значений, где исходный код не обрабатывается вообще не кодирует URI и не требует никакого дополнительного клиентского JavaScript:

<form action="/search"><input name="q"></form>

По сути, именно так работает поисковая форма Google (или DuckDuckGo, или Yahoo!, или…). Метод по умолчанию — GET (используйте строку запроса), поле ввода получает сокращенное «имя поля» q (сокращение от query). Используя немного JS, можно обойти кодировку формы и применить запрос напрямую, как "строка запроса" — но не забудьте закодировать URI/URL значение/запрос/термины поиска перед объединением! (И это может обойти любой сбор «данных формы», выполняемый вашей резервной веб-платформой, например, вам нужно будет вытащить request.query_string самостоятельно.)

person amcgregor    schedule 01.01.2020
comment
Итак, как я могу обрабатывать пустые входные данные, отправленные из формы? например: у меня есть 4 поля, a, b, c, d, и я нажимаю поиск, просто выдавая a, и теперь, как мне с этим справиться? - person Codenewbie; 01.01.2020
comment
только для a у меня есть одно условие, аналогично для всех, а также у меня есть условия для их комбинаций, например (если a и b) ищутся, сделайте что-нибудь........ как обрабатывать все это в методе просмотра при маршруте? - person Codenewbie; 01.01.2020
comment
когда я сделал что-то вроде отправки только lettersearch поля, которое я получил в URL-адресе (127.0.0.1:5000/ search?lettersearch=6&wordsearch=) и 400 bad request - person Codenewbie; 02.01.2020
comment
@Codenewbie С этой ситуацией лучше справляется чат, который я не могу предоставить. Обновите свой первоначальный вопрос с помощью MCVE, например. на Codepen.io, воспроизводя то, как вы создаете эту форму. Потому что это выглядит очень странно, и его невозможно отладить, не видя формы, в которой это создается. - person amcgregor; 02.01.2020
comment
Я решил это, сэр, я делаю ошибку, вы упомянули запрос strings, но из формы я отправляю целое число, глупо, что я запрашивал с string 6, а не 6, извините за все ваше время на это. - person Codenewbie; 02.01.2020

В колбе вы можете получить аргументы из самого запроса.

    from flask import request

    @app.route('/endpoint')
    def myfn():
        val1 = request.args.get('arg1')
        val2 = request.args.get('arg2')

Таким образом, вы можете сделать что-то вроде этого во внешнем интерфейсе:

<form action='/word-search' method='GET'>
    <input type='text' name='wordlen' />
    <input type='text' name='wordtype' />
    <input type='text' name='word' />
    <input type='submit' />
</form>

И в конце сервера,

@app.route('/words-search', methods=['GET', 'POST'])
def wordsearch(word):
    wordlen = request.args.get('wordlen')
    wordtype = request.args.get('wordtype')
    word = request.args.get('word')
    ...
person npk    schedule 31.12.2019
comment
Итак, при отправке мне не нужно ничего делать из шаблона? - person Codenewbie; 31.12.2019
comment
Нет, вы можете отправить форму - person npk; 31.12.2019
comment
здесь я не использую какую-либо форму, потому что я просто показываю поля и кнопку поиска, при поиске/отправке я хочу сопоставить точный URL-адрес в представлении, поэтому сценарий, который я использовал в шаблоне - person Codenewbie; 31.12.2019
comment
отправка формы на «/» — более простой способ. Если вы хотите отправить его с помощью кода js, вы все равно можете использовать метод формы. Если вы каким-то образом не можете использовать методы формы, вы можете загрузить URL-адрес как '?arg1=val1&arg2=val2' - person npk; 31.12.2019
comment
Я обновил свой вопрос, может быть, теперь вы это понимаете - person Codenewbie; 31.12.2019
comment
Я обновил свой ответ. На самом деле это очень просто; не так уж и запутанно - person npk; 31.12.2019
comment
Дело в том, что я хочу показать в URL не просто words-search , а `words-‹word›` - person Codenewbie; 31.12.2019
comment
в примере URL будет отображаться как /word-search?wordlen=10&wordtype=text&word=helloworld. Это не в порядке с вами? потому что это стандарт - person npk; 31.12.2019
comment
да, я понимаю, но вместо этого я хочу показать как 6-буквенные слова-...... - person Codenewbie; 31.12.2019
comment
Я не совсем понял, что вы пытаетесь сделать. Насколько я понял, вы пытаетесь направить различные URL-адреса в одну и ту же функцию. Вы можете перенаправлять различные URL-адреса, как вы это делали, но это НЕ правильный путь. - person npk; 31.12.2019
comment
Давайте продолжим обсуждение в чате. - person Codenewbie; 31.12.2019