Why my url appears as a post request when its get django - python

I have some templates in a django project. I'm trying to save them in the the url with a post request even though I specify it in the html document.
Here's my views.py
`
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .forms import WcaForm, IdForm
from . import wcaScraper
# Create your views here.
def id(response):
form = IdForm(response.GET)
return render(response, "main/id.html", {"form": form})
def idresults(response):
print(response.method)
if response.method == "GET":
print(wcaScraper.getDataByName(response.GET.get('name')))
return render(response, "main/nameresults.html", {"ids": wcaScraper.getDataByName(response.GET.get('name'))})
def search(response):
form = WcaForm(response.GET)
return render(response, "main/search.html", {"form": form})
def results(response):
wcaData = wcaScraper.getDataById(response.GET.get('id'))
variablePassed = {
"id": response.GET.get('id'),
"single3": wcaData[0].single,
"avg3": wcaData[0].avg,
"single2": wcaData[1].single,
"avg2": wcaData[1].avg,
"single4": wcaData[2].single,
"avg4": wcaData[2].avg,
"single5": wcaData[3].single,
"avg5": wcaData[3].avg,
"single6": wcaData[4].single,
"avg6": wcaData[4].avg,
"single7": wcaData[5].single,
"avg7": wcaData[5].avg,
"blind3single": wcaData[6].single,
"blind3avg": wcaData[6].avg,
"fmsingle": wcaData[7].single,
"fmavg": wcaData[7].avg,
"ohsingle": wcaData[8].single,
"ohavg": wcaData[8].avg,
"clocksingle": wcaData[9].single,
"clockavg": wcaData[9].avg,
"megasingle": wcaData[10].single,
"megaavg": wcaData[10].avg,
"pyrasingle": wcaData[11].single,
"pyraavg": wcaData[11].avg,
"skewbsingle": wcaData[12].single,
"skewbavg": wcaData[12].avg,
"squaresingle": wcaData[13].single,
"squareavg": wcaData[13].avg,
"blind4single": wcaData[14].single,
"blind4avg": wcaData[14].avg,
"blind5single": wcaData[15].single,
"blind5avg": wcaData[15].avg,
"multisingle": wcaData[16].single,
"multiavg": wcaData[16].avg,
}
return render(response, "main/results.html", variablePassed)
`
And my html template
<html>
<h1>Search by name</h1>
<form method="get" action="/idresults">
{% csrf_token %} {{form}}
<button type="submit">Search</button>
</form>
<p>or</p>
Search by WCA Id
</html>
I tried printing the method and I got `GET
But the url looks like this
http://localhost:8000/idresults/?csrfmiddlewaretoken=v1jXO1Tei1eU0l8FbgF49qeJU5zKJlTQUUkggmW0oYgrG5WcLOvJhBb08PBY3klg&name=zemdegs

Your url does not appear as a POST, but as a GET. If your problem is the token, just remove the {%csrf_token%} from your template.

Related

How to load chart in Django Template

I have an Altair chart which I want to render in a Django Template. The chart is converted into a json object in the views. Here is the code
views.py
def home(request):
if request.method=='POST':
year = request.POST['year']
df, cus_dict = generate_df(year)
bar_obj = barGraphAltair(year, df)
bar_obj = json.loads(bar_obj.to_json())
print(bar_obj)
context = {'bar': bar_obj}
return render(request, 'index.html', context=context)
return render(request, 'index.html')
template
<div id='altair-viz'>
{% if bar %}
{{ bar|safe }}
{% endif %}
</div>
This just prints the json in the template. I know I have to use Vega to render the graph but I am not sure how to do that in jinja syntax
A temp solution
One way I got this to work, is by creating a different view and calling that view in the template as follows
views.py
def renderAltair(request):
df, cus_dict = generate_df('2017')
bar_obj = barGraphAltair('2017', df)
bar_obj = json.loads(bar_obj.to_json())
return JsonResponse(bar_obj)
template
<script>
vegaEmbed('#altair-viz', "{% url 'altair' %}")
</script>
This works, but as you can see from the original code, I get the year by submitting a form and passing that to the function for generating the graph. So I need the graph to be created in the home view
You can try this way.
def home(request):
if request.method=='POST':
year = request.POST['year']
context = {'year': year}
return render(request, 'index.html', context=context)
return render(request, 'index.html', {})
Not passing data in home view, will get that using json view.
template
<div id='altair-viz' data-url="{% url 'altair' %}?year={{year}}"></div>
<script>
var data_url = $('#altair-viz').attr('data-url');
vegaEmbed('#altair-viz', data_url)
</script>
and get data function
def renderAltair(request):
year = request.GET.get('year')
df, cus_dict = generate_df(year)
bar_obj = barGraphAltair(year, df)
bar_obj = json.loads(bar_obj.to_json())
return JsonResponse(bar_obj)

Using data returned from forms in Django

Sorry for being a little new. My goal is to use the data collected from a user form to output a graph. The user inputs an initial 'price' then submits this number, it then goes into my formulas written in python and then django should display a chart in the same HTML file. I'm currently stuck on how to use data from 'POST'.
For example, if I'd like to take the cleaned_data from 'strike1' and multiply it by 4, then display it on the webpage, how would I go about doing that?
views.py
from django.shortcuts import render
from .forms import DataForm
# Create your views here.
def data(request):
if request.method == 'POST':
form = DataForm(request.POST)
if form.is_valid():
strike1 = form.cleaned_data['strike1']
strike2 = form.cleaned_data['strike2']
strike3 = form.cleaned_data['strike3']
strike4 = form.cleaned_data['strike4']
strategy = form.cleaned_data['strategy']
price = range(0,50)
premium1 = form.cleaned_data['premium1']
premium2 = form.cleaned_data['premium2']
premium3 = form.cleaned_data['premium3']
premium4 = form.cleaned_data['premium4']
contracts = form.cleaned_data['contracts']
form = DataForm()
return render(request, 'form.html', {'form': form})
forms.py
from django import forms
class DataForm(forms.Form):
strategy = forms.ChoiceField(
choices=[('Long Call', 'Long Call'), ('Long Put', 'Long Put'), ('Short Call', 'Short Call',),
('Short Put', 'Short Put'), ('Bull Call Spread', 'Bull Call Spread'),
('Bear Put Spread', 'Bear Put Spread'), ('Straddle', 'Straddle'),
('Butterfly Spread', 'Butterfly Spread'),
('Box Spread', 'Box Spread'), ('Iron Condor', 'Iron Condor')])
strike1 = forms.FloatField()
strike2 = forms.FloatField()
strike3 = forms.FloatField()
strike4 = forms.FloatField()
premium1 = forms.FloatField()
premium2 = forms.FloatField()
premium3 = forms.FloatField()
premium4 = forms.FloatField()
contracts = forms.IntegerField()
form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Website</title>
</head>
<body>
<form method="'post">
{% csrf_token %}
{{ form }}
<button type="Submit">Generate</button>
</form>
</body>
</html>
I'd say the cleanest way to do it, is to build up a new "content" and render a new page in the POST processing section. For example:
from django.shortcuts import render
from .forms import DataForm
# Create your views here.
def data(request):
if request.method == 'POST':
form = DataForm(request.POST)
if form.is_valid():
# ... do you processing as it
return render(request, 'output.html', {'data': whatever})
form = DataForm()
return render(request, 'form.html', {'form': form})
You could also just let it call through to the original render function, but you'll need to include whatever information you want in the context like {"form: form} already is.
U need to create 2 views for using data.(basicly)
One for form, one for your formulas.
in urls.py
path('formpage/', views.formpage, name='form_view'),
path('result/', views.result, name='MY_calculator'),
in views.py
def formpage(request):
return render(request, '-----Template-----',)
def result(request):
x=request.GET.get('xval')
y=request.GET.get('yval')
result=x+y
return render(request, '-----Result Template----', {'result': result})
and form action for template. ("" instead of)
<form action="{% url 'MY_calculator' %}">
You can set initial values to your form and render them to the same template within the same URL.
Here is an example:
def data(request):
if request.method == 'POST':
form = DataForm(request.POST)
if form.is_valid():
strike1 = form.cleaned_data['strike1'] * 2
strike2 = form.cleaned_data['strike2'] * 3
# Set initials
# strike1 & strike2 new values will be rendered as default values
# in your form
form = DataForm(initial={'strike1': strike1, 'strike2': strike2})
return render(request, 'form.html', {'form': form})
form = DataForm()
return render(request, 'form.html', {'form': form})
Also, you must pay attention, in your template HTML you wrote "'post" instead of "post".

Django: cannot save data from Form in DB

I've been following a tutorial, but making small changes, doesn't allow me to save the form in DB.
However, I know the model is correct because I can save objects from within shell.
I'm not getting any error, after submitting I'm redirected to the home page.
But if I submit form and then go to the admin, I see the registered model, but with no records on in (except the ones saved through shell). Howcome?
models.py:
class TamaniosCantidades(models.Model):
TAMANIOS = (('498', '2" x 2"',), ('499', '3" x 3"',),
('500', '4" x 4"',), ('501', '5" x 5"',))
CANTIDADES = (('100', '50',), ('100', '100',),
('150', '150',))
tamanios = models.CharField(max_length=10, choices=TAMANIOS)
cantidades = models.CharField(max_length=10, choices=CANTIDADES)
forms.py:
from django import forms
from .models import TamaniosCantidades
class TamaniosCantidadesForm(forms.ModelForm):
class Meta:
model = TamaniosCantidades
fields = ['tamanios', 'cantidades']
urls.py:
from . import views
from django.urls import path, include
urlpatterns = [
path('', views.index),
path('productos/', views.productos),
path('post_url/', views.post_treasure, name='post_treasure'),
path('post_url_tamanioscantidades/', views.post_tamanioscantidades, name='post_tamanioscantidades'),
]
views.py:
def index(request):
treasures = Treasure.objects.all()
form = TreasureForm()
tamanioscantidades_form = TamaniosCantidadesForm()
return render(request, 'main_app/index.html', {'treasures': treasures,
'form': form,
'tamanioscantidades_form': tamanioscantidades_form})
def post_tamanioscantidades(request):
tamanioscantidades_form = TamaniosCantidadesForm()
if tamanioscantidades_form.is_valid():
tamanioscantidades_form.save(commit = True)
return HttpResponseRedirect('/')
html:
<div class="row">
<form action="post_url_tamanioscantidades/" method="post">
{% csrf_token %}
{{ tamanioscantidades_form.as_p }}
<input type="submit" value="Submit"/>
</form>
</div>
def post_tamanioscantidades(request):
tamanioscantidades_form = TamaniosCantidadesForm()
if tamanioscantidades_form.is_valid():
tamanioscantidades_form.save(commit = True)
return HttpResponseRedirect('/')
This method creates a blank TamaniosCantidadesForm, which isn't valid, so it never gets saved.
You probably want to do something like TamaniosCantidadesForm(request.POST), to actually fill in the form with the submitted data.

invalid django form makes is_valid method always return false

My django form is invalid and so the .is_valid method never returns true. As a result, I am getting an "Expected HttpResponse but received None" type of error because my code never executes what is within the if-condition. I am wondering how to make my form valid. I am new to django so I am probably missing something obvious. Here is my code:
views.py
template_name1 = 'multiplication/detail.html'
template_name2 = 'multiplication/multiplied.html'
class myForm(forms.Form):
quantity1 = forms.IntegerField(required=False)
quantity2 = forms.IntegerField(required=False)
form = myForm()
def get(request):
return render(request,template_name1,{'form': form} )
def multiply_two_integers(x,y):
return x*y
def post(request):
if (form.is_valid()):
x = request.POST.get('quantity1')
y = request.POST.get('quantity2')
product = multiply_two_integers(x, y)
return render(request, template_name2, {'form': form, 'product':
product })
template_name1
<h1>Multiplication Function</h1>
<form action = "{% url 'multiplication:post' %}" method = "post">
{{ form.as_p }}
{% csrf_token %}
<input type = "submit" value ="Multiply">
<!--<button type="submit"> Multiply </button>-->
<h1>{{product}}</h1>
</form>
template_name2
<h1>{{product}}</h1>
urls/multiplication
from django.urls import path
from multiplication import views
app_name = 'multiplication'
urlpatterns = [
# /multiplication/
path('', views.get, name = 'get'),
path('multiplied', views.post, name='post')
]
This code is very strange. You seem to have a set of functional views, but are trying to randomly use some concepts from class-based views.
The reason why your form is not valid is because you never pass any data to it; an unbound form cannot be valid. You should not be instantiating the form outside of a view; you need to do it in the view, and when the request is a POST you should pass the POST data to it.
In function-based views you should not define separate functions for get and post. Combine them, as sown in the Django docs.
There is another point that you have missed about the error message; your reaction to it telling you that you have not returned a response if the form is invalid is to ask "why isn't it valid", but you should also do what it says and return a response in this case; the form will sometimes be actually invalid, and you should deal with this case.
Finally, to get the data from the form you should use form.cleaned_data, not request.POST.
def multiply_two_integers(x,y):
return x*y
def my_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if (form.is_valid()):
x = form.cleaned_data['quantity1']
y = form.cleaned_data['quantity2']
product = multiply_two_integers(x, y)
return render(request, template_name2, {'product': product })
else:
form = MyForm()
return render(request,template_name1,{'form': form} )

New to DJango need to fill form with initial data in get_data

Here is my html:
{% block my_dashboard_main %}
<form action="status/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
My urls.py:
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'status/$', views.status),
url(r'thanks/$', views.thanks),
)
Here is my views.py:
STATUS_CHOICES = (
("GOOD", "Good"),
("BAD", "Bad"),
("COMPROMISED", "Compromised")
)
def thanks(request):
return render(request, "my_dashboard/ssa_panel/sent.html')
class SsaForm(forms.Form):
status = forms.ChoiceField(choices = STATUS_CHOICES, label="Status:")
def status(request):
print("STATUS CALLED method=",request.method)
if request.method == 'POST': # If the form has been submitted...
form = SsaForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
print("redirect to THANKS!")
return HttpResponseRedirect('thanks/') # Redirect after POST
else:
print("Requesting form\n")
form = SsaForm(initial = {"status", "Good"}) # An unbound form
return render(request, 'my_dashboard/ssa_panel/index.html', {
'form': form,
})
class IndexView(views.APIView):
# A very simple class-based view...
template_name = 'my_dashboard/ssa_panel/index.html'
def get_data(self, request, context, *args, **kwargs):
print("GET_DATA Called", context)
# Add data to the context here...
return context
The first time my page renders the I want the status to show up. It doesn't. Just the Submit button. After I submit once the "Status: [Good] <- combo box" is there. I want to go get the data for the for status in get_data and set it but I don't know how. do I set context['status']="Good" or something like that?
I'm obviously new to DJango and REST stuff.
You are trying to construct your initial value dictionary incorrectly using a comma (,) instead of a colon and also using the wrong choice key. Instead of
form = SsaForm(initial = {"status", "Good"})
try
form = SsaForm(initial = {"status": "GOOD"})

Categories

Resources