probleme rendering in django - python

i'm using an api to get informations about coronavirus cases around the world and i have an issue in the last line of code
from django.shortcuts import render
import requests
from django import forms
from django.views.generic import TemplateView
from .forms import homeform
def home(request):
if request.method =='POST':
form = homeform(request.POST)
if form.is_valid():
text = form.cleaned_data
field = text['name']
print(field)
country = field
else:
form = homeform()
country = 'algeria'
url = "https://covid-193.p.rapidapi.com/statistics"
querystring = {"country": country}
headers = {
'x-rapidapi-host': "covid-193.p.rapidapi.com",
'x-rapidapi-key': "36b864062emshac7e191eb5087e6p169e6bjsn24c86f3408c1"
}
response = requests.request("GET", url, headers=headers, params=querystring).json()
data = response['response']
print(data)
d = data[0]
context = {
'all': d['cases']['total'],
'recovered': d['cases']['recovered'],
'deaths': d['deaths']['total'],
'new': d['cases']['new'],
'serioz': d['cases']['critical'],
'active':d['cases']['active'],
'deaths_new':d['deaths']['new']
}
return render(request, 'index.html',{'form':form}, context)
here i have a problem with rendering the page it just shows my html code in the webpage but when i remove context from the last line of code evrything becomes normal , please help me

I think you are trying to pass two context dictionaries. Your {'form':form} is in the place of the context argument so your context isn't actually getting passed as a context. Add the form to the context dictionary in the line above return and remove {'form':form} from your render function.

I think you need to change your code to this :
return render(request, 'index.html',{'form':form,
'context':context})
This way you will get both in the html file.

Related

How to fix a Django view that is not returning an HttpResponse Object? (CS50 Project 1)

I am receiving the following error when submitting a form.
ValueError at /edit_entry/hi/
The view encyclopedia.views.edit_entry didn't return an HttpResponse object. It returned None instead.
Here is the views.py that is triggering the error.
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpResponseRedirect("/wiki/" + title)
else:
form = NewEditEntryForm()
return render(request, "encyclopedia/edit_entry.html",{
"form": NewEditEntryForm(),
"title": title,
"content": util.get_entry(title)
})
What is the issue and how can I fix it?
(I also need help prepopulating the form with already existing data. I have tried using initial, but that has not worked. What is the best way to prepopulate the form with existing data?)
util.save_entry
def save_entry(title, content):
"""
Saves an encyclopedia entry, given its title and Markdown
content. If an existing entry with the same title already exists,
it is replaced.
"""
filename = f"entries/{title}.md"
if default_storage.exists(filename):
default_storage.delete(filename)
default_storage.save(filename, ContentFile(content))
sorry, I thought that you have a model.
# on util.py
def get_entry_content(title):
filename = f"entries/{title}.md"
return default_storage.open(filename).read()
# on views.py
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpResponseRedirect("/wiki/" + instance.title)
else:
content = util.get_entry_content(title)
initial_dict = {
"title" : title,
"content" : content,
}
form = NewEditEntryForm(initial=initial_dict)
return render(request, "encyclopedia/edit_entry.html", {
"form": form,
})
All right, I think if this is not doing what you want, i would test the save_entry function in the console, creating and updating to see if it works or not.

Django2: After form submission is there a better way to 'wipe' the POST to stop re-submission

I have a django application and on one page I have several forms for different models. I would like a 'success' message, which is easy to do by just adding to the context after form submission/validation. However, this leaves the possibility of re-submission of the form, which would just produce an error back to the page, but it still annoys me.
urls:
url_patterns = [
re_path(r'^manager/$', Manager.as_view(), name='manager'),
.......more.....
]
views.py:
class Manager(LoginRequiredMixin, View):
template_name = 'results/manager_templates/manager.html'
form1 = Form1
form2 = Form2
login_url = '/'
redirect_field_name = 'redirect_to'
def get(self, request, *args, **kwargs):
form1 = self.form1()
form2 = self.form2()
context = {
'form1': form1,
'form2': form,}
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
submit_clicked = request.POST.get('submit')
form1 = self.form1()
form2 = self.form2()
context = {}
if submit_clicked == 'Form 1':
form1 = self.form1(request.POST)
if form1.is_valid():
form1.save()
context['message'] = 'Form 1 successful'
# reset the form
form1 = self.form1()
# return HttpResponseRedirect(
# reverse('results:manager',
# ))
else:
print('NOT VALID')
elif submit_clicked == 'Form 2':
... do same stuff as above ...
context['form1'] = form1
context['form2'] = form2
return render(request, self.template_name, context)
If I were to uncomment out the HttpResponseRedirect out, after the form was validated and added like so:
return HttpResponseRedirect(
reverse('results:manager',
))
Then it returns me to my page, and if i refresh the form isnt re-submitted. However I can't pass this an argument without it going through the url:
i.e if I were to write:
return HttpResponseRedirect(
reverse('results:manager',
kwargs={'success':'success'}
))
I get the error:
Reverse for 'manager' with keyword arguments '{'success': 'success'}' not found. 1 pattern(s) tried: ['manager/$']
and if I change urls.py to:
url_patterns = [
re_path(r'^manager/$', Manager.as_view(), name='manager'),
re_path(r'^manager/(?P<success>)$', Manager.as_view(), name='manager'),
]
I get the error:
Reverse for 'manager' with keyword arguments '{'success': 'success'}' not found. 2 pattern(s) tried: ['manager/(?P<success>)$', 'manager/$']
Is there anyway to pass HttpResponseRedirect variables that dont need to be added to url regex? Or is there any other way to 'reset' my request.POST so that forms dont get re-submitted, without using HttpResponseRedirect?
As you've found, you should redirect after a successful post to prevent duplicate requests.
When you changed the urls, you didn't add any characters to match in your success group.
re_path(r'^manager/(?P<success>\w+)$', Manager.as_view(), name='manager'),
Another option is to store the variable in the querystring, e.g. /manager/?success=success, then you can retrieve the value from request.GET after the redirect.
You could also store data in the session, or use the messages framework.

How to pass data through an AJAX request in django?

I want to retrieve data from the database when the bottom of the page is hit.
Now, what I have so far:
urls.py
urlpatterns = [
url(r'^$', feedViews.index, name='index'),
url(r'^load/$', feedViews.load, name='load'),
]
views.py
def index(request):
if request.method == 'GET':
context = {
'entry_list': Entry.objects.filter()[:5],
}
return render(request,'index.html',context)
else:
return HttpResponse("Request method is not a GET")
def load(request):
if request.method == 'GET':
context = {
'entry_list': Entry.objects.filter()[:1],
}
return render(request,'index.html',context)
else:
return HttpResponse("Request method is not a GET")
index.html
...
<script>
$(window).on("scroll", function() {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log( "TEST" );
$.ajax(
{
type:"GET",
url: "/load",
data:{
},
})
}
});
</script>
...
Basicaly it loads 5 items at the beginning and what I try to achieve is that it loads 1 more as soon as I hit the bottom of the page.
So jQuery works beacuase the console.log('Test') works and in my terminal it says
"GET /load/ HTTP/1.1" 200 484
which is fine as well.
I think I messed up the ajax somehow. I am not sure though.
As you can probably tell I am a nooby but any help is highly appreciated.
Use something like this:
import json
from django.http import JsonResponse
def index(request):
if request.method == 'GET':
context = {
'entry_list': Entry.objects.filter()[:5],
}
return JsonResponse(json.dumps(context), safe=False)
else:
return JsonResponse({"err_msg": "Failed"})
Try it:
import json
from django.core import serializers
from django.http import JsonResponse
def index(request):
if request.method == 'GET' and request.is_ajax():
# Return objects
entry = Entry.objects.filter()[:5]
# serializers
entry2 = serializers.serialize('json', entry)
# convert JSON
entry3 = [d['fields'] for d in json.loads(entry2)]
data = dict()
data["entry"] = entry3
return JsonResponse(data)

How can I skip to a template and render the request data to it using ajax?

This is the first page, in there I can use ajax to request url, and pass request data to it.
My ajax code is below:
$.ajax({
type:'post',
url:'/app_api/server_payment/',
contentType:'application/json',
data:JSON.stringify({'params':buy_data}),
dataType:'json',
success:success_func
})
function success_func(response){
console.log(response)
}
In the views.py:
def server_payment(request):
if request.method == 'POST':
is_login = request.session['is_login']
if is_login:
print ('server_payment_2 ', is_login) # it prints
return render(request, 'app_admin/payment.html')
else:
return render(request, 'frontend/login.html')
In the views.py I want to render the payment.html and skip to it.
This is my payment.html.
But the server.html page did not skip to the payment.html, and I don't know how to realize it.
I tried use the self.location=/app_api/server_payment/ but I can not pass the data with post method.
There are some detail information in the first snapshot.
You need to check AJAX header before you make any logic and return JsonResponce
request.is_ajax()
More in the documentation
def server_payment(request):
if request.method == 'POST':
is_login = request.session['is_login']
if is_login:
print('server_payment_2 ', is_login) # it prints
if request.is_ajax():
return JsonResponse({'foo': 'bar'})
return render(request, 'app_admin/payment.html')
else:
return render(request, 'frontend/login.html')

Links in django_facebook app result in Bad Request: missing signed_request

I'm using the django_facebook library installed on pythonanywhere.
When I click a link from one view to another, I get an error message:
400 Bad Request
Missing signed_request.
Could someone give me the brief on how links work in a facebook app?
Removing the #canvas_only decorator doesn't solve the problem, because I need access to the graph api.
Here's the code:
views.py:
from django.shortcuts import render
from django_facebook.decorators import canvas_only
#from django_facebook.decorators import facebook_required
#from django.utils.decorators import method_decorator
from models import Poem, Share
from django import forms
from django.views.generic import View
class PoemEntryForm(forms.Form):
words = forms.CharField( widget=forms.widgets.Textarea(), initial='ENTER\nPOEM\nHERE\nONE\nWORD\nPER\nLINE' )
#canvas_only
def home(request):
me = request.facebook.graph.get_object('me')
my_username = me['username']
request.session['username'] = my_username
try:
poems = Poem.objects.filter(user=my_username)
except Poem.DoesNotExist:
poems = []
# convert poems into tuples of information relevant to the home page
# sort them in reverse chronological order
# ie: title and created
poems = [(poem.title(), poem.created) for poem in sorted(poems, key=lambda poem: poem.created, reverse=True)]
try:
shared = Share.objects.filter(shared_to=my_username)
except Share.DoesNotExist:
shared = []
shared = [(poem.title(), poem.user, poem.created) for poem in sorted(shared, key=lambda poem: poem.created, reverse=True)]
return render(request, 'home.html', {
'me': me,
'my_poems': poems,
'shared': shared,
})
class Create(View):
##method_decorator(canvas_only)
def get(self, request, *args, **kwargs):
#self.me = request.facebook.graph.get_object('me')
form = PoemEntryForm(request.GET)
return render(request, 'create.html', {
'form': form,
'debug': request.session['username']
})
##method_decorator(canvas_only)
def post(self, request, *args, **kwargs):
if request.session['username']:
form = PoemEntryForm(request.POST)
poem = Poem()
poem.user = request.session['username']
poem.text = request.POST['words']
poem.save()
return render(request, 'submitted.html', {})
else:
return render(request, 'error_submitting.html', {})
submitted.html:
<html>
<body>
<h3>You submitted a poem</h3>
Home
</body>
</html>
So the deal is this.
When the django, or whatever is doing the replying replies with: missing signed_request., what it really means is that the session doesn't contain an entry of key 'signed_request'. You can find this request in the POST data of the initial request. Save it in the session, and you're good to go.

Categories

Resources