I have a query form which gets input from 3 fields and display the related matched content from the database models. But i am trying to select only one field from the three fields on the form and need to get data from database models related to that field?
views.py
from django.shortcuts import render
from search.forms import ModuleForm
from django.http import HttpResponse
from search.models import Module,Metamodule,Release
def searchview(request):
if request.method == 'GET':
form = ModuleForm(request.GET)
if form.is_valid():
release_num = form.cleaned_data['release_num']
metamodule_name = form.cleaned_data['metamodule_name']
module_name = form.cleaned_data['module_name']
results = Module.objects.filter(metamodule__release__number=release_num).filter(metamodule__name=metamodule_name).filter(name=module_name)
return render(request,'search/search_result.html',{'form': form, 'results': results})
else:
form = ModuleForm()
return render(request, 'search/search_form.html',{'form': form})
forms.py
from django import forms
from search.models import Module,Release,Metamodule
class ModuleForm(forms.Form):
release_num = forms.ModelChoiceField(queryset=Release.objects.all(),empty_label='Pick a Release')
metamodule_name = forms.ModelChoiceField(queryset=Metamodule.objects.all(),empty_label='Pick a Meta module')
module_name = forms.ModelChoiceField(queryset=Module.objects.all(),empty_label='Pick a Module')
def clean_release_number(self):
try:
release_num = self.cleaned_data.get["release_num"]
metamodule_name = int(self.cleaned_data["metamodule_name"])
module_name = int(self.cleaned_data["module_name"])
except:
release_num = None
metamodule_name = None
module_name = None
if release_num and Module.objects.exclude(metamodule__release__number=release_num).exists():
raise forms.ValidationError("Please enter a valid release number.")
else:
return release_num
How to modify the view to accept single input and display the data even though the other two fields are not provided with data?
Consider checking for each field and filtering on that field value individually.
if form.is_valid():
release_num = form.cleaned_data['release_num']
metamodule_name = form.cleaned_data['metamodule_name']
module_name = form.cleaned_data['module_name']
results = Module.objects.all()
if release_num:
results = results.filter(metamodule__release__number=release_num)
if metamodule_name:
result = results.filter(metamodule__name=metamodule_name)
if module_name:
result = results.filter(name=module_name)
return render(request,'search/search_result.html',{'form': form, 'results': results})
It's up to you to validate the input using your clean_fieldname()
methods. Consider using def clean(self)
to perform multi-field validation (like having at least one field filled in).
Why are you processing your form input on GET
? Is there a reason why you're submitting form data with GET
and ignoring POST
?
Also, while it's good that you're checking form.is_valid()
and implementing clean_fieldname
methods, you need to add an else
clause to if form.is_valid():
that handles form.errors
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.