how to have a single search API using path parameters (No form used)

妖精的绣舞 提交于 2020-01-07 08:04:11

问题


I have been using this view for searching a word as:

db refers mongo connection (just for ref)

@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)

In index.html template I have been doing this to match this above url as:

    <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>

Does this can be done in more dynamic way ?, I mean this only works for word and not for other selections,or combination of selections as below:

The search input looks as:

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

Now the API I have does match only if I send word , but how can I write a single API such that it should match all the possible combinations like word length + word type, word + word type (queries I would define on own)

What I have tried is :

@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)

and in templates the 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>

But confused if there are combination's like, 6-letter-words-of-verbs verb is a word type here

Also how to match the same URL for these combination's from template as i was doing with JQuery used in script above?

Is this the correct way? , I guess writing all possible routes in views and match it from template with the conditions in Jquery is a bad idea ,

any help/guiding links are appreciated ,TIA


回答1:


Based on my comment-suggested recommendation to not ignore the behavior of the client browser, and to follow the intent of the definition of a URI (where /foo+bar and /bar+foo must not represent the same resource), the following is all you actually require, and handles URI-encoding of the values automatically, where your original did not handle URI encoding at all, and requires no additional client-side JavaScript of any kind:

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

This is essentially how Google's (or DuckDuckGo's, or Yahoo!'s, or…) search form operates. Default method is GET (use a query string), input field given the abbreviated "field name" q (short for query). Using a tiny bit of JS one can bypass the form-encoding and apply the query directly as the "query string" — but remember to URI/URL-encode the value/query/search terms before combining! (And that doing this may bypass any "form data" collection performed by your backing web framework, e.g. you'll need to pull out request.query_string yourself.)




回答2:


In flask you can get the arguments from the request itself.

    from flask import request

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

So you can do something like this in front-end:

<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>

And at server end,

@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')
    ...


来源:https://stackoverflow.com/questions/59539950/how-to-have-a-single-search-api-using-path-parameters-no-form-used

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!