Validate a form with django

2

I'm on my first project mounted on a server and I've chosen the django framework. I'm making an application that shows values from a mineral database that I've made, and that has a search field with the form tag:

<div class="container" style="width:75%;margin:auto;padding:10px">
  <form style="width:75%;margin:auto" type="get" action="./../result" style="margin: 0" accept-charset="UTF-8">
    <input  id="search_box" type="text" name="search_box"  placeholder="Mineral o grupo..." >
    <button class="btn btn-success" id="search_submit" type="submit" >Buscar mineral o grupo</button>
  </form>
</div>

In the view I have:

def result(request):
valorpasado=str(request.get_full_path).replace("<bound method WSGIRequest.get_full_path of <WSGIRequest: GET '/result/?","")
valorpasado=valorpasado.replace("'>>","")
if request.method == 'GET': # If the form is submitted
    dicty = {
        "minerales":Mine180.objects,
        "search_query":request.GET.get('search_box', None),
        "valorpasado":valorpasado

    }


    return render(request,'mine180/result.html',{'dicty':dicty})

I have the route configured in urls.py:

urlpatterns = [

  url(r'^result/$',viewmine.result, name='result'),

]

If the result entered is a mineral from the list all correct, I show the result in the route of the action 'domain / result /? query But I do not know if I'm doing it right, because if it does not coincide with any mineral it must remain on the page. I do not really understand where I should do the validation, whether in the model or in the view. I've tried some things like redirect for the original path if the query does not match, but I do not think this is the correct method.

In case someone falls here and is interested, I managed to implement what I needed quickly thanks to Germán's help.

And my urls.py is:

urlpatterns = [
url(r'^mine180/ficha/(?P<mine_id>[0-9]+)/$',viewmine.ficha),
url(r'^mine180/consulta/',viewmine.consulta),
] 

the form leads to mine180 / query with a sign? :

<form style="width:75%;margin:auto" action="http://127.0.0.1:8000/mine180/consulta/?" method="get">
<input size="40"id="search_mine" type="text" name="search_mine" value="{{ current_name }}" placeholder="Busque mineral o grupo...">
<input type="submit" value="OK">

and in the function of the view that manages the query (def query), I take the query. I have to improve it, but the code shown, if the search matches a mineral of the DB, opens the template of the tab (and the template receives parameters of the mineral in particular, such as the id); if you can not find it, return the original search_box template, adding a message that you have not found the mineral. Here I can implement the search filters, as Germán has indicated to me, and I will do it.

def consulta(request):
#desde search_box
query = request.GET.get('search_mine', '')
mineid = 0
for mineral in Mine180.objects.all():
    if mineral.name1==query:
        print 'encontro oro'
        mineid = mineral.id
        print mineid
#print 'viene de consulta'
if mineid != 0:
    print 'lo encontro'
    return render(request,'mine180/ficha.html',{'mineid':mineid})
else:
    print 'No lo encontro'
    minerales = {
        "minerales":Mine180.objects,
        "mensaje":"No se encontro el mineral: "+query
    }
    return render(request,'mine180/mine180.html',minerales)
    
asked by Universal_learner 14.11.2017 в 21:43
source

1 answer

2

Well, I'll help you explain several points.

First is the attribute action of the tag form , this attribute what it does is tell the browser that all the fields that are in that form, when listening to an event submit will send them to a certain route or url , in this case it would be /result/ that was what you defined in your file of urls.py ; Django offers you a way to do this a little faster and in a more scalable way with the template tag {% url 'result' %} , where result must be the same written as the value you put to the attribute name of the url that you want to call.

Then in your view, I see that you do str(request.get_full_path) . Usually by conventions, in python and django, when something starts with get it refers to a method, and not a property. What happens here is that you are calling a representation of a method and not the method as such, remember that the methods must be called, you can check if something is a method or function with the function that python brings for you, called callable , in the following way:

if callable(request.get_full_path) is True:
    valor = request.get_full_path()

That only if you do not know if it is a function or method, of the rest, if you know do not call the callable if it does not just call your function with the parentheses at the end. In this case, I already told you that it is a method. So you do not have to do the replace you're doing.

Then something that you lack, is to understand the querysets. Unfortunately I can not explain that because there are many tutorials on the internet, in addition to the same documentation of django that is the best in explaining it. But basically comes the part of getting the data out of the database so you can display it in your view. Django does this thanks to the querysets and his api. But to give you an idea you can do something like this:

from django.db.models import Q

url = request.get_full_path()

query = request.GET.get('search_box', '')
q = Q(material__icontains=query) | Q(mina__icontains=query)
queryset = Mine180.objects.filter(q)

dicty = {
    "minerales": queryset, "search_query": query, "valor_pasado": url
}
return render(request, 'mine180/result.html', dicty)

Since I do not know your models, I invented the fields as material and mina but you must put the fields according to what you want to search and filter.

Any questions comments

    
answered by 14.11.2017 / 23:48
source