I have a index.html file which has the submit button. I want the functionality that when I click submit button, python function should get called in background but the rendering view of index.html should stay same. Right now every time I click on submit button a new copy of index.html is getting loaded. Here are my codes
index.html
<form action = "submit" method = "post">
<p>latitude <input type = "text" id = "Latbox" name = "Latbox" /></p>
<p>Longitdue <input type = "text" id = "Lonbox" name = "Lonbox" /b></p>
<p><input type = "submit" value = "submit" /></p>
</form>
My views.py file is as follow :
from django.shortcuts import render
from django.views.generic import TemplateView
class HomePageView(TemplateView):
def get(self, request, **kwargs):
return render(request, 'index.html', context=None)
def submit(request):
LAT=request.POST['Latbox']
LON= request.POST['Lonbox']
print (LAT, LON)
return render(request,'index.html',context=None)
I am new to django. Can I get some pointer or answer as to how to solve this.
Use the same view to perform both actions.
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<p><input type = "submit" value = "submit" /></p>
</form>
At forms.py:
class LocationForm(forms.Form):
latitude = form.CharField()
longitude = form.CharField()
Then at views.py you do something like this:
class HomePageView(TemplateView):
template_name = "index.html"
def get(self, request, **kwargs):
form = LocationForm()
return render(request, self.template_name, {"form": form})
def post(self, request, **kwargs):
form = LocationForm(request.POST)
if form.is_valid():
pass # do something with form.cleaned_data
return render(request, self.template_name, {"form": form})
It is not fully covered in the tutorial but take a look at forms and generic views.
Related
OK so I'm trying to create a page that will have a search form of Well,
I get the contents of the search in the page ex: (http://127.0.0.1:8000/wellsheet/ODN20)
I used this code
urls.py file
path('wellsheet/<slug:Evt_id>', views.wellsets, name='WellSheetg'),
views.py
def wellsets(request, Evt_id):
serchedWl = WellSheets.objects.filter(WellID__WellID__exact=Evt_id)
context ={
'title': 'Eventstopost',
'Wellslist':serchedWl,
'WIDSHT':Evt_id,
}
return render(request, 'Home/WELLINFO/W_TchD/wellshts.html', context)
in addition to this page I want to add another well ,and I have a model form to add in same page using crispy.
urls.py
path('wellsheet/<slug:WeelN>/', views.welshetad2.as_view(), name='AddWellSheet'),
views.py
class welshetad2(LoginRequiredMixin, CreateView):
model = WellSheets
template_name = 'Home/WELLINFO/W_TchD/wellshts.html'
form_class = UploadWSF2
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
but in my page I can't render the crispy form
<div class="border p-3 mb-3 mt-3 w3-round-large w3-light-grey border-dark">
<form method="POST">
{% csrf_token %}
<div class="form-row"><div class="form-group mb-0">
{{ form.as_p }}
</div></div>
this is my page
page
My goal is to see a page like this
My Goal
Hi the problem is solved by using one def as:
views.py
def wellsets(request, pk):
serchedWl = WellSheets.objects.filter(WellID__WellID__exact=pk)
form= UploadWSF2(request.POST or None)
context ={
'title': 'Wellssht',
'Wellslist':serchedWl,
'WIDSHT':pk,
'form':form,
}
return render(request, 'Home/WELLINFO/W_TchD/wellshts.html', context)
and the page will show tow results a Form and results of search
I have a DetailView Based on a model ( A ) and on the same template I have a ModelFormView from a model B which has FK to model (A)
The data from form doesn't get saved to the database.
This is the DetailView:
class LocationView(DetailView):
template_name = "base/stocks/location.html"
model = LocationStock
def get_context_data(self, **kwargs):
context = super(LocationView, self).get_context_data(**kwargs)
context['form'] = OutsModelForm
return context
def get_object(self):
id_ = self.kwargs.get("id")
return get_object_or_404(LocationStock, id=id_)
This is the FormView:
class OutsAdd(FormView):
form_class = OutsModelForm
success_url = reverse_lazy('base:dashboard')
def form_valid(self, form):
return super().form_valid(form)
This is the url.py:
path('locations/<int:id>', LocationView.as_view(), name='location-detail'),
path('locations/outs', require_POST(OutsAdd.as_view()), name='outs-add'),
This is the template:
<form method="POST" action="{% url 'outs-add' %}" >
<div class="modal-content">
{% csrf_token %}
{% render_field form.quantity placeholder="Quantity"%}
{% render_field form.id_year placeholder="Year"%}
{% render_field form.id_location placeholder="ID Location"%}
</div>
<div class="modal-footer">
<input class="modal-close waves-effect waves-green btn-flat" type="submit" value="Save">
</div>
</form>
The data gets POSTED in the /locations/outs but is not saving to the actual database.How can I save it ?
The functionality of Django's FormView is really only meant to display a form on a GET request, show form errors in the case of form_invalid, and redirect to a new URL if the form is valid. In order to persist the data to the database you have two options. First you can simply call form.save() in your FormView:
class OutsAdd(FormView):
form_class = OutsModelForm
success_url = reverse_lazy('base:dashboard')
def form_valid(self, form):
form.save()
return super().form_valid(form)
Or, you can use the generic CreateView. Django's CreateView is similar to a FormView except it assumes it's working with a ModelForm and calls form.save() for you behind the scenes.
I am trying to return a bound form that has been modified and has some arbitrary text and HTML inserted into it. I have done some research and have been able to successfully insert some arbitrary text into a bound form but I haven't found any way to render the injected HTML as HTML. It renders as plain text. How can I achieve my goal?
Here is the code:
# views.py
def multi_text(request):
if request.method == 'POST':
data = request.POST.copy()
form = MultilineForm(data=data)
if form.is_valid():
cd = form.cleaned_data
form.data['text'] = '<i>Hello hello</i>'
return render(request, 'multi_text.html', {'form': form})
else:
form = MultilineForm()
return render(request, 'multi_text.html', {'form': form})
# forms.py
class MultilineForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['text'].widget.attrs.update({'class': 'form-control'}, verbose_name='Text', placeholder='Type your text here...')
self.data['text'] = '...'
class Meta:
model = Multiline
fields = ['text']
widgets = {
'text': Textarea(attrs={}),
}
# template.html
<form method="post" action="" class="form">
{% csrf_token %}
{{ form.text.as_widget }}
<span class="input-group-btn">
<input type="submit" value="Check" class="form-control btn btn-primary">
</span>
</form>
Hey i am trying to use modelchoicefield to get a dropdown list in html. But the submission of form yields a invalid form. My code is given below.
views.py
class SubjectSelectFormView(View):
form_class = SubjectSelectForm
template_name = 'study/select_subject.html'
def get(self, request):
form = self.form_class(user=request.user)
return render(request, self.template_name, {'form':form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
subject = models.Subject.objects.get(name=form['name'])
return HttpResponseRedirect('study:quiz', subject.subject_id)
else:
return HttpResponse('<h1>Failed</h1>')
forms.py
class SubjectSelectForm(forms.Form):
name = forms.ModelChoiceField(queryset=Subject.objects.all().order_by('name'), widget=forms.Select())
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(SubjectSelectForm,self).__init__(*args, **kwargs)
self.fields['name'].queryset = Subject.objects.filter(user_id=user)
html
{% extends 'basic_home_app/base.html' %}
{% block content %}
<br>
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Start">
</form>
{% endblock %}
First you should always render the same template with the bound form when a posted form is found to not be valid, this way you can display errors to the user:
def post(self, request):
form = ...
if form.is_valid():
...
else:
return render(request, self.template_name, {'form':form})
Inside your template, you can display errors using either:
{{ form.errors }} # all form errors
{{ form.non_field_errors }} # form errors that aren't for one specific field, use this if you're displaying the field errors separately
or
{{ form.name.errors }} # just the errors for one specific field
Second, I assume you want to initialise your form the same way when it's posted as when it's first displayed (empty) to the user via the get() request:
def post(self, request):
form = self.form_class(request.POST, user=request.user) # note the user
Otherwise your form.__init__() method will set as queryset only Subject objects where user_id is None.
This is rather weird. I've been using Django forms for a long time and can't figure this out.
I have a small form with 1 field for "Quantity". Whenever I submit the form nothing happens and it NEVER get's into my condition to check if the request method is a POST. I have put a pdb in the code as well and it never reaches. I am not sure why. Here is the code.
views.py
def show_product(request, product_slug, template_name='catalog/product.html'):
product_cache_key = request.path
product = cache.get(product_cache_key)
if not product:
product = get_object_or_404(Product, slug=product_slug)
cache.set(product_cache_key, product, settings.CACHE_TIMEOUT)
categories = product.categories.filter(is_active=True)
if request.method == 'POST':
import pdb; pdb.set_trace() # it NEVER hit's this
postdata = request.POST.copy()
form = ProductAddToCartForm(request, postdata)
if form.is_valid():
cart.add_to_cart(request)
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
url = urlresolvers.reverse('show_cart')
return redirect(url)
else:
form = ProductAddToCartForm(request=request)
form.fields['product_slug'].widget.attrs['value'] = product_slug
request.session.set_test_cookie()
context = RequestContext(request, locals())
return render_to_response(template_name, context)
forms.py
class ProductAddToCartForm(forms.Form):
quantity = forms.IntegerField(widget=forms.TextInput(attrs={'class': 'input-quantity', 'placeholder': 'Qty'}), error_messages={'invalid': 'Please enter a valid quantity.'}, min_value=1)
product_slug = forms.CharField(widget=forms.HiddenInput())
def __init__(self, request=None, *args, **kwargs):
self.request = request
super(ProductAddToCartForm, self).__init__(*args, **kwargs)
def clean(self):
if self.request:
if not self.request.session.test_cookie_worked():
raise forms.ValidationError("Sorry, please enable your cookies.")
return self.cleaned_data
template
<form method="post" action=".">
{% csrf_token %}
{{ form.quantity.errors }}
{{ form.quantity }}
<input type="submit" name="submit" value="Add to Cart" class="btn btn-danger" />
{{ form.product_slug }}
</form>
When I click "Add to Cart" the URL goes from http://localhost:8000/product/arm-glove/ to this one http://localhost:8000/product/arm-glove/?csrfmiddlewaretoken=RFG0F1Lg0Eu3GcDhtYwPPCpy9Oct5zCX&quantity=2&submit=Add+to+Cart&product_slug=arm-glove
What am I missing here?
Turns out there was an unclosed tag used for the search which is a GET request so the form's POST was never being seen.