I have created a formset for users to add and remove forms as necessary using Django's empty_form and jQuery. However, when the form is submitted I am being thrown a validation error. I have initialized the ManagementForm, so I am not sure as to what the issue is. Any help would be greatly appreciated.
views.py
def presales(request):
PresalesFormSet = formset_factory(PresalesForm, extra=1, can_delete=True)
if request.method == 'POST':
presales_formset = PresalesFormSet(request.POST)
if presales_formset.is_valid():
selected_opportunity = request.POST.get('selected_opportunity')
for presales_form in presales_formset:
task_description = request.POST.get('task_description')
hours = request.POST.get('hours')
obj = Presales()
obj.opportunity = selected_opportunity
obj.taskDescription = task_description
obj.hours = hours
obj.save()
else:
presales_form = PresalesForm()
presales_formset = PresalesFormSet()
context = {'presales_formset': presales_formset, 'presales_form': presales_form, 'my_opportunities': my_opportunities}
return render(request, 'website/presales.html', context)
template.html
{{ presales_formset.management_form }}
<form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="presalesForm"
method="post" name="presalesForm">
<div class="field">
<label class="label is-large">High Level Task List</label>
</div>
{% csrf_token %}
{% for presales_form in presales_formset.forms %}
{{ presales_form.field_errors }}
{{ presales_form.errors }}
</form>
{% endfor %}
<div id="empty_form" style="display: none;">
{{ presales_formset.empty_form }}
<form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="emptyPresalesForm"
method="post" name="presalesForm">
{% csrf_token %}
</form>
</div>
forms.py
# special field names
TOTAL_FORM_COUNT = 'TOTAL_FORMS'
INITIAL_FORM_COUNT = 'INITIAL_FORMS'
MIN_NUM_FORM_COUNT = 'MIN_NUM_FORMS'
MAX_NUM_FORM_COUNT = 'MAX_NUM_FORMS'
ORDERING_FIELD_NAME = 'ORDER'
DELETION_FIELD_NAME = 'DELETE'
# default minimum number of forms in a formset
DEFAULT_MIN_NUM = 0
# default maximum number of forms in a formset, to prevent memory exhaustion
DEFAULT_MAX_NUM = 1000
class PresalesForm(forms.Form):
class Meta:
model = Presales
fields = ('selected_opportunity', 'task_description', 'hours', 'selected_engineer_level', 'total_price')
You need some additional data: form-TOTAL_FORMS, form-INITIAL_FORMS and form-MAX_NUM_FORMS. This data is required for the ManagementForm. Seems like you didn’t provide this management data. It should look like this:
data = {
'form-TOTAL_FORMS': '1',
'form-INITIAL_FORMS': '0',
'form-MAX_NUM_FORMS': '',
'form-0-title': '',
'form-0-pub_date': '',
}
That management_form should be inside your formset, like:
<form action="{% url 'presales' %}" class="presales_formset" data-total-url="{% url 'presales_total' %}" id="presalesForm"
method="post" name="presalesForm">
{{ presales_formset.management_form }}
<div class="field">
<label class="label is-large">High Level Task List</label>
</div>
{% csrf_token %}
{% for presales_form in presales_formset.forms %}
{{ presales_form.field_errors }}
{{ presales_form.errors }}
</form>
Related
when i used ajax in my project the form.is_valid() method not validating the form. it showing the 'this field required error' but i access that using request.POST means i fill all the fields.
'''
this is html code which render the django model form
##HTML FORM##
<form action="" method="post" enctype="multipart/form-data" id="reception_form" novalidate> {% csrf_token %}
{% for field1 in form1 %}
<label for="{{field1.id_for_label}}"> {{field1.label}} </label> {{field1}}
<div>
{% if field1.errors %}{% for error in field1.errors %} <small class="errorlist">{{error}}</small> {% endfor %}{% endif %}
</div>
{% endfor %}
{% for field2 in reception %}
{% if field2.name != 'gender' %}
<label for=" {{field2.id_for_label}} "> {{field2.label}} </label> {{field2}}
<div>
{% if field2.errors %}{% for error in field2.errors %} <small class="errorlist">{{error}}</small> {% endfor %}{% endif %}
</div>
{% endif %}
{% endfor %}
{% for radiofield in reception.gender %}
{{radiofield.tag}}
<label for=" {{radiofield.id_for_label}} "> {{radiofield.choice_label}} </label> <br>
{% endfor %}
<input type="submit" value="Add Reception" name="Add Reception" class="btn btn-secondary mb-3" >
</form>
----------
## Ajax ##
$('#reception_form').submit(function(e){
console.log(" submit pressed")
e.preventDefault();
let Rnm = $('#id_username').val();
let Rfnm = $('#id_first_name').val();
let Rlnm = $('#id_last_name').val();
let Rem = $('#id_email').val();
let Rpwd = $('#id_password1').val();
let Rmob = $('#id_mob_no').val();
let Rcty= $('#id_city').val();
let Rdob = $('#id_dob').val();
let Rpr = $('#id_profile_photo').val();
let Rgen = $("input[name='gender']:checked").val()
let Rcsr = $("input[name='csrfmiddlewaretoken']").val()
reception_data = {Rusername : Rnm , Rfirst_name:Rfnm ,Rlast_name:Rlnm ,Remail:Rem , Rpassword:Rpwd, RmMob_no:Rmob , Rcity:Rcty , RBirth_Date :Rdob, Rprofile:Rpr, Rgender:Rgen , csrfmiddlewaretoken:Rcsr};
//console.log(reception_data)
$.ajax({
url: "{% url 'AddReception' %}" ,
type : 'POST',
data : reception_data,
dataType:'json',
success: function(data){
console.log("ajax executed");
console.log(data);
}
});
});
----------
admin_home view render the initial form and user information
## views ##
## 1) home##
def Admin_home(request):
print("admin Home")
user = request.user
admin = Admin.objects.get(pk=user)
# print(request)
form1 = Register()
reception = Register_Reception()
param = {'user':user , 'admin':admin , 'form1':form1 , 'reception':reception}
return render(request , "patients/admin/home.html" , param)
----------
This view function handles the ajax request but is_valid() returns false
## 2) Add Reception ##
def Add_reception(request):
if request.method == "POST":
form1 = Register(request.POST) #usercreation form
form2 = Register_Reception(request.POST , request.FILES) #reception profile form
print(form1.is_valid())
print(form1.errors)
print(request.POST['Rpassword'])
return HttpResponse("form submited")
'''
i think you are using jquery, right? Then i would try to serialize the form data like this:
reception_data = $("#reception_form").serialize()
Maybe this is better to send the POST data to the form...
Best,
jingo
i want search from all my model in database , so i create this search functions for do this ... but always i got ' No results for this search '
how to fix this ?
view.py:
def search(request):
if request.method == 'GET':
query= request.GET.get('q')
submitbutton= request.GET.get('submit')
if query is not None:
home_database= Homepage.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
pcprograms_database= PCprogram.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
androidapk_database= AndroidApks.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
androidgames_database= AndroidGames.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
antiruvs_database= Antivirus.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
systems_database= OpratingSystems.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
pcgames_database= PCgames.objects.filter(name__icontains=query,app_contect__icontains=query,page_url__icontains=query,app_image__icontains=query)
results= list(chain(home_database,pcprograms_database,androidapk_database,androidgames_database,antiruvs_database,systems_database,pcgames_database))
context={'results': results,
'submitbutton': submitbutton}
return render(request, 'html_file/enterface.html', context)
else:
return render(request, 'html_file/enterface.html')
else:
return render(request, 'html_file/enterface.html')
html search form :
<form id="search_form" action="{% url 'search' %}" method="GET" value="{{request.GET.q}}">
<input id="search_box" type="text" name="q" value="{{request.GET.q}}"
placeholder=" Search For ... "/>
<input id="search_button" type="submit" name="submit" value="Search"/>
</form>
html file :
{% if submitbutton == 'Search' and request.GET.q != '' %}
{% if results %}
<h1> <small> Results for </small><b>{{ request.GET.q }}</b> : </h1>
<br/><br/>
{% for result in results %}
<label id="label_main_app"> <img id="img_main_app_first_screen" src="{{result.app_image.url}}" alt="no image found !" height="170" width="165" > {{result.name}} <br><br> <p id="p_size_first_page"> {{result.app_contect}} <br> <br> <big> See More & Download </big> </p>
</label>
{% endfor %}
{% else %}
<h3> No results for this search </h3>
{% endif %}
{% endif %}
any help please ?
If you are trying to filter with multiple model fields you need Q from django.db.models
Homepage.objects.filter(Q(name__icontains=query)&Q(app_contect__icontains=query),....
I'm trying to show User's search query in the Search Box on the results page. A very basic problem, but for some reason, it doesn't work for me
My views.py looks like:
def search(request):
result_list = []
if request.method == 'POST':
query = request.POST['query'].strip()
if query:
print(query)
print(type(query))
# Run our Webhose search function to get the results list!
result_list = run_query(query)
context_dict = {'result_list': result_list, 'query': query}
context_dict = {'result_list': result_list}
return render(request, 'rango/search.html', context_dict)
my search.html template is below:
{% block body_block %}
<div>
<h1>Search with Rango</h1>
<br/>
<form class="form-inline" id="user_form"
method="post" action="{% url 'search' %}">
{% csrf_token %}
<div class="form-group">
<input class="form-control" type="text" size="50"
name="query" value="{{query}}" id="query" />
</div>
<button class="btn btn-primary" type="submit" name="submit"
value="Search">Search</button>
</form>
<div>
{% if result_list %}
<h3>Results</h3>
<!-- Display search results in an ordered list -->
<div class="list-group">
{% for result in result_list %}
<div class="list-group-item">
<h4 class="list-group-item-heading">
{{ result.title }}
</h4>
<p class="list-group-item-text">{{ result.summary }}</p>
</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endblock %}
Any advice?
My context_dict was being overwritten.
Please find the solution below:
def search(request):
query = ''
result_list = []
if request.method == 'POST':
query = request.POST['query'].strip()
if query:
print(query)
print(type(query))
# Run our Webhose search function to get the results list!
result_list = run_query(query)
context_dict = {'result_list': result_list, 'query': query}
return render(request, 'rango/search.html', context_dict)
I found an similar question here, but unlike there and unlike in django official tutorial , I don't have a separate Choice class. How can I restrict every user to vote just one? What should I change in my code?
my models.py:
from django.contrib.auth.models import User
class Law(models.Model):
#some code here
yes_votes = models.IntegerField(default=0)
no_votes = models.IntegerField(default=0)
class Voter(models.Model):
user = models.ForeignKey(User)
law = models.ForeignKey(Law)
my views.py:
class LawDetailView(generic.DetailView):
model = Law
template_name = 'law_detail.html'
def get_queryset(self):
"""
Excludes any petitions that aren't published yet.
"""
return Law.objects.filter(pub_date__lte=timezone.now())
class LawResultsView(generic.DetailView):
model = Law
template_name = 'law_results.html'
def law_yes_vote(request, law_id):
if Voter.objects.filter(law_id=law_id, user_id=request.user.id).exists():
return render(request, 'law_detail.html', {
'law': p,
'error_message': "Sorry, but you have already voted."
})
else:
p = get_object_or_404(Law, pk=law_id)
p.yes_votes += 1
p.save()
return HttpResponseRedirect(reverse('laws:law_results', args=(p.id,)))
def law_no_vote(request, law_id):
if Voter.objects.filter(law_id=law_id, user_id=request.user.id).exists():
return render(request, 'law_detail.html', {
'law': p,
'error_message': "Sorry, but you have already voted."
})
else:
p = get_object_or_404(Law, pk=law_id)
p.no_votes += 1
p.save()
return HttpResponseRedirect(reverse('laws:law_results', args=(p.id,)))
my law_detail.html:
{% if request.user.is_authenticated %}
{% if error_message %}
<h1 >{{ error_message }}</h1>
{% else %}
<div class="row" id="row-voting">
<form action="{% url 'laws:law_yes_vote' law.id %}" method="post">
{% csrf_token %}
<button class="btn btn-success" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" >
<label >YES</label>
</form>
<form action="{% url 'laws:law_no_vote' law.id %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" >
<label >NO</label>
</form>
</div>
{% endif %}
{% else %}
<h1>Please, register</h1>
{% endif %}
It looks like you have forgotten to create the voter instance after the user has voted.
def law_yes_vote(request, law_id):
if Voter.objects.filter(law_id=law_id, user_id=request.user.id).exists():
return render(request, 'law_detail.html', {
'law': p,
'error_message': "Sorry, but you have already voted."
})
else:
p = get_object_or_404(Law, pk=law_id)
p.yes_votes += 1
p.save()
Voter.objects.create(law_id=law_id, user_id=request.user.id)
return HttpResponseRedirect(reverse('laws:law_results', args=(p.id,)))
You'll need to update law_no_vote in the same way.
I'm trying to make a search form for Django.
Its a typical search form and then returns a table of matches. I wish to paginate the tables returned.
The problem lies in the Previous and Next buttons.
The links for the return query goes to /records/search/?query=a (search sample is a)
The page outputs the table and its previous and next links. However the links redirect to /records/search/?page=2 and the page displays a blank table.
Any help on which links I should pass for Prev/Next?
search.html:
{% extends 'blank.html' %}
{% block content %}
<div class="row">
<form id="search-form" method="get" action=".">
{{ form.as_p }}
<input type="submit" value="Search" />
</form>
</div>
<br><br>
//display table code//
{% if is_paginated %}
<div class="pagination">
<span class="step-links">
{% if agent_list.has_previous %}
forrige
{% endif %}
<span class="current">
Page {{ agent_list.number }} of {{ agent_list.paginator.num_pages }}.
</span>
{% if agent_list.has_next %}
Next
{% endif %}
</span>
</div>
{% endif %}
{% endblock %}
and the search view:
def search_page(request):
form = SearchForm()
agents = []
show_results=False
if request.GET.has_key('query'):
show_results=True
query=request.GET['query'].strip()
if query:
form=SearchForm({'query': query})
agents = \
Agent.objects.filter(Q(name__icontains=query))
paginator = Paginator(agents, 10)
page = request.GET.get('page')
try:
agents = paginator.page(page)
except PageNotAnInteger:
agents = paginator.page(1)
except EmptyPage:
agents = paginator.page(paginator.num_pages)
variables = RequestContext(request,
{ 'form': form,
'agent_list': agents,
'show_results': show_results,
'is_paginated': True,
}
)
return render_to_response('search.html', variables)
I've seen the similar questions but I can't understand/make them work. Any help?
Edit:
For a quickfix (haven't really looked at the cons)
I added a variable in my view:
variables = RequestContext(request,
{ 'form': form,
'agent_list': agents,
'show_results': show_results,
'is_paginated': True,
**'query': query,**
}
)
Where query without the quotes is the recieved query variable.
Then simply change the URL to:
Previous
If you have a better way of answering the question, please do or appending a URL to your currently opened URL.
I would recommend putting the solution in a template tag like so:
myapp/templatetags/mytemplatetags.py:
from django import template
register = template.Library()
#register.simple_tag
def url_replace(request, field, value):
d = request.GET.copy()
d[field] = value
return d.urlencode()
#register.simple_tag
def url_delete(request, field):
d = request.GET.copy()
del d[field]
return d.urlencode()
Then from templates do:
{% load mytemplatetags %}
...
previous
you can use {{ request.get_full_path }} this tag to get current url.
Next
this worked for me
The below works before and after a search form has been submitted:
Views.py
class PostListView(ListView):
model = Post #.objects.select_related().all()
template_name = 'erf24/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts' # default >> erf24/post_list.html
ordering = ['date_posted']
paginate_by = 3
def is_valid_queryparam(param):
return param != '' and param is not None
def invalid_queryparam(param):
return param == '' and param is None
class SearchView(ListView):
model = Post #.objects.select_related().all()
template_name = 'erf24/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts' # default >> erf24/post_list.html
ordering = ['date_posted']
paginate_by = 3
def get_queryset(self): # new
key = self.request.GET.get('key')
minp = self.request.GET.get('min')
maxp = self.request.GET.get('max')
if is_valid_queryparam(key):
obj = Post.objects.filter(Q(content__icontains=key) | Q(location__icontains=key)).distinct().order_by('date_posted')
if is_valid_queryparam(minp):
obj = Post.objects.filter(Q(price__gte=minp)).distinct().order_by('date_posted')
if is_valid_queryparam(maxp):
obj = Post.objects.filter(Q(price__lte=maxp)).distinct().order_by('date_posted')
if is_valid_queryparam(minp) & is_valid_queryparam(maxp):
obj = Post.objects.filter(Q(price__gte=minp) & Q(price__lte=maxp)).distinct().order_by('date_posted')
if is_valid_queryparam(key) & is_valid_queryparam(minp) & is_valid_queryparam(maxp):
obj = Post.objects.filter(Q(content__icontains=key) | Q(location__icontains=key)).distinct()
obj = obj.filter(Q(price__gte=minp) & Q(price__lte=maxp)).order_by('date_posted')
if invalid_queryparam(key) & invalid_queryparam(minp) & invalid_queryparam(maxp):
obj = Post.objects.all()
return obj
url.py
urlpatterns = [
path('', PostListView.as_view(), name='erf24-home'),
path('search/', SearchView.as_view(), name='erf24-search'),
]
Home.html
<form action="{% url 'erf24-search' %}" method="GET">
<div class="form-group">
<label for="inputAddress">Search keyword</label>
<input type="text" class="form-control" id="key" name="key" placeholder="keyword">
</div>
<label for="">Price</label>
<div class="form-row">
<div class="form-group col-md-6">
<input type="number" class="form-control" id="min" name="min" placeholder="min price">
</div>
<div class="form-group col-md-6">
<input type="number" class="form-control" id="max" name="max" placeholder="max price">
</div>
</div>
<button type="submit" class="btn btn-primary btn-sm mt-1 mb-1">Search</button>
<button type="reset" class="btn btn-secondary btn-sm mt-1 mb-1">Clear</button>
</form>
{% for post in posts %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}" alt="">
{{ post.author }}
<small class="text-muted">{{ post.date_posted }}</small>
<!-- use |date: "specs" to filter date display -->
</div>
<h2>
{{ post.price }}
</h2>
<p class="article-content">{{ post.content }}</p>
<p class="article-content">{{ post.location }}</p>
<p><a class="like-btn" data-href="{{ post.get_api_like_url }}" href="">{{ post.likes.count }}
{% if user in post.likes.all %} Unlike
{% else %} Like
{% endif %}
</a></p>
</div>
{% for image in post.image_set.all %}
<img class="account-img" src="{{ image.image.url }}" alt="">
{% endfor %}
</article>
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
First
Previous
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
{{ num }}
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
{{ num }}
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
Next
Last
{% endif %}
{% endif %}
Worked like a charm :) Enjoy!
You can use {{ request.get_full_path }} template tag
Next
you can use this, I use it because I use filters in the url itself, so all the url params are used to build the next or previous url
import re
from django import template
register = template.Library()
PAGE_NUMBER_REGEX = re.compile(r'(page=[0-9]*[\&]*)')
#register.simple_tag
def append_page_param(value,pageNumber=None):
'''
remove the param "page" using regex and add the one in the pageNumber if there is one
'''
value = re.sub(PAGE_NUMBER_REGEX,'',value)
if pageNumber:
if not '?' in value:
value += f'?page={pageNumber}'
elif value[-1] != '&':
value += f'&page={pageNumber}'
else:
value += f'page={pageNumber}'
return value
then, in your pagination nav you can call it like this:
{% append_page_param request.get_full_path page_obj.previous_page_number %}