How can I show a message in Django url? - django

My views.py works properly under the path in urlpattern I have defined.
I have a for loop and I want to show a message in the browser screen I've tried with httpResponse and JsonResponse, but I cant or get some errors.
My views.py function is:
def all_disconnect (request):
try:
url_cnc = 'http://**********************'
auth = {'username':'*****', 'password':'*******'}
log = requests.post(url_cnc, data=auth)
log.cookies['SESSION']
cookie_log = log.cookies['SESSION']
peticion = requests.Session()
peticion.headers.update({'Cookie' : 'SESSION='+cookie_log})
#--------------DOWN IS THE PROBLEM-----------------------------------
for meter in all_meter:
x = peticion.post('http://150.214.144.246:8443/ws/v1/cg/dc/meters/'+ meter +'/control/plc/Disconnect/immediate')
HttpResponse ('El meter '+meter+' ha sido desconectado')
return JsonResponse("fin", safe=False)
except ValueError as e:
return JsonResponse(e.args[0])
I can print "fin", but if I put JsonResponse inside the loop to print each "meter" I get some error.
Do you know how to do this?

Related

Django - Get response to return image without saving file to models

I am using the tmdb api to return movie info as well as images.
Steps below of Get logic
Api request is made which provides movie info as well as "backdrop_path"
I then use this path to make another request for the jpg related to that movie.
Blocker
I'm unable to then output that jpg. It currently returns a url path as below.
Views.py
from django.shortcuts import render
from django.views.generic import TemplateView
import requests
import urllib
# Create your views here.
def index(request):
# Query API with user input
if 'movie' in request.GET:
api_key = 'api'
id = request.GET['movie']
url = 'https://api.themoviedb.org/3/search/movie?api_key={}&language=en-US&query={}&include_adult=false'
response = requests.get(url.format(api_key,id))
# successful request
if response.status_code == 200:
# Parse json output for key value pairs
tmdb = response.json()
# save image jpg
backdrop_path = tmdb['results'][0]['backdrop_path']
url = 'https://image.tmdb.org/t/p/original/{}'
gg = urllib.request.urlretrieve(url.format(backdrop_path), 'test.jpg')
context = {
'title': tmdb['results'][0]['original_title'],
'overview': tmdb['results'][0]['overview'],
'release_date': tmdb['results'][0]['release_date'],
'vote_average': tmdb['results'][0]['vote_average'],
'vote_count': tmdb['results'][0]['vote_count'],
'backdrop_path' : tmdb['results'][0]['backdrop_path'],
'jpg' : gg
}
return render(request, 'home.html', {'context': context})
else: # returns homepage if invalid request
return render(request, 'home.html')
else: # Homepage without GET request
return render(request, 'home.html')
urlretrieve doesn't return the image ready to be used, instead it returns a tuple with the local name of the file and the headers (as an HTTPMessage object as you can see in your example), which is what you're seeing.
However, I don't think returning a file in your response is ideal, nor it would work in your scenario. Since you seem to be using templates, what I would do is return the image url and use it in an image HTML tag, like this <img src="{{ jpg }}"/>

Publish a custom Django Flatpage at a set date and time

I have a custom Flatpage model:
from django.contrib.flatpages.models import FlatPage
class MyFlatPage(FlatPage):
publish = models.DateTimeField()
so that I can add a publish date in the future.
Now, I don't have a proper list of flatpages on the front end, my use for frontpages is more like 'one-offs', where I specific the URL and all that. For example, 'about', '2019prize', 'Today's walk', stuff like that.
The urls.py is set up to catch all the flatpages with:
from django.contrib.flatpages import views
re_path(r'^(?P<url>.*/)$', views.flatpage)
How can I set these pages I create to be displayed only after the publish date has arrived? I know that I can filter them by looking up something like pages.filter(publish__lte=now). Where and how should I put that code though?
Additional information
I suppose I need to create a custom view, is that correct? The original view is in ../lib/python3.8/site-packages/django/contrib/flatpages/views.py:
def flatpage(request, url)
if not url.startswith('/'):
url = '/' + url
site_id = get_current_site(request).id
try:
f = get_object_or_404(FlatPage, url=url, sites=site_id)
except Http404:
if not url.endswith('/') and settings.APPEND_SLASH:
url += '/'
f = get_object_or_404(FlatPage, url=url, sites=site_id)
return HttpResponsePermanentRedirect('%s/' % request.path)
else:
raise
return render_flatpage(request, f)
#csrf_protect
def render_flatpage(request, f):
if f.registration_required and not request.user.is_authenticated:
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(request.path)
if f.template_name:
template = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
else:
template = loader.get_template(DEFAULT_TEMPLATE)
f.title = mark_safe(f.title)
f.content = mark_safe(f.content)
return HttpResponse(template.render({'flatpage': f}, request))
How can I extend this, adding my if publish__lte=now code?
What I did is copy-paste the view code from ../lib/python3.8/site-packages/django/contrib/flatpages/views.py to my app.views, rename the two functions, and add the following to render_myflatpage:
def render_myflatpage(request, f):
[...]
if f.publish > now:
f.content = 'This content will be published on ' + str(f.publish)
I then assigned the new view in the catch-all urls.py code:
re_path(r'^(?P<url>.*/)$', myflatpage)
I know this goes against the DRY protocol; this works for me for the time being. If there's a more elegant solution please do let me know.

Django -- Views MultiValueDictKeyError

I want to return 4 different versions of the homepage
Homepage with search bar. No data present from API
Homepage with search bar. Data present from API
Homepage with search bar. No data present if request doesn't exist in API
Homepage with search bar. No data present if submit button is hit without any data being entered.
Version two, three and four all work.
However version 1, the homepage without a GET request is not returned. Due to:
MultiValueDictKeyError at / 'city'" in the views.py file.
How can this be resolved? Any help will be greatly appreciated
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
]
views.py
from django.shortcuts import render
import requests
def index(request):
# Query API with user input
payload = {'q': request.GET['city'], 'appid': 'API-KEY'}
response = requests.get('http://api.openweathermap.org/data/2.5/weather', params=payload)
# successful request
if response.status_code == 200:
# Parse json output for key value pairs
e = response.json()
context = {
'city_name': e['name'],
'weather':e['weather'][0]['main'],
'description' : e['weather'][0]['description'],
'temp' : e['main']['temp'],
'pressure':e['main']['pressure'],
'humidity':e['main']['humidity'],
'visibility':e['visibility'],
'wind_speed':e['wind']['speed'],
'wind_deg':e['wind']['deg']
}
return render(request, 'index.html', {'context': context})
else: # returns homepage if invalid city name is given in form
return render(request, 'index.html')
Instead of calling request.GET['city'] directly, check if city is set first, like:
if 'city' in request.GET:
payload = {'q': request.GET['city'], 'appid': 'API-KEY'}

Process received data from python requests library to show it in template

i am try to get live data from Raspberry pi and showing it to my django template. i could send data by 'requests' library and receiv it by Django REST. but the problem is in my django for example i post data to localhost/a how could i can render this data to localhost/b for example.
i tried django session. i thought that when i in localhost/b maybe i can use session but that dose not work.
rpi-req.py
# this is code from Raspberry pi, to send(POST) data to django
while True:
# print(cam.get_frame())
da = {'rpiLive': "30 or any data"}
res = requests.post(url, files=da, timeout=1000, auth=('anas', '****'))
print(res.status_code)
time.sleep(1)
views.py inside django.
# this code is from django-views, to receive data
#api_view(['POST'])
def video_feed(request):
if request.method == 'POST':
reqData = request.FILES['rpiLive']
try:
return HttpResponse(gen22(request, reqData),
content_type='multipart/x-mixed-replace; boundary=reqData')
except Exception as q:
print("live Data aborted!!!", q)
return HttpResponseRedirect('/live2/')
return HttpResponseRedirect('/')
And gen22 function is:
def gen22(request, data):
a = data
time.sleep(0.5)
con = {
"anas": a,
"con_tag": "live",
}
time.sleep(1)
return render(request, "dahsboard.html", con)
urls.py
path('<int:user_id>/<tag>/', views.dahsboard, name='dahsboard'),
path('live/', views.video_feed, name='live-frame2'),

Django: custom 404 handler that returns 404 status code

The project I'm working on has some data that needs to get passed to every view, so we have a wrapper around render_to_response called master_rtr. Ok.
Now, I need our 404 pages to run through this as well. Per the instructions, I created a custom 404 handler (cleverly called custom_404) that calls master_rtr. Everything looks good, but our tests are failing, because we're receiving back a 200 OK.
So, I'm trying to figure out how to return a 404 status code, instead. There seems to be an HttpResponseNotFound class that's kinda what I want, but I'm not quite sure how to construct all of that nonsense instead of using render_to_response. Or rather, I could probably figure it out, but it seems like their must be an easier way; is there?
The appropriate parts of the code:
def master_rtr(request, template, data = {}):
if request.user.is_authenticated():
# Since we're only grabbing the enrollments to get at the courses,
# doing select_related() will save us from having to hit database for
# every course the user is enrolled in
data['courses'] = \
[e.course for e in \
Enrollment.objects.select_related().filter(user=request.user) \
if e.view]
else:
if "anonCourses" in request.session:
data['courses'] = request.session['anonCourses']
else:
data['courses'] = []
data['THEME'] = settings.THEME
return render_to_response(template, data, context_instance=RequestContext(request))
def custom_404(request):
response = master_rtr(request, '404.html')
response.status_code = 404
return response
The easy way:
def custom_404(request):
response = master_rtr(...)
response.status_code = 404
return response
But I have to ask: why aren't you just using a context processor along with a RequestContext to pass the data to the views?
Just set status_code on the response.
Into your application's views.py add:
# Imports
from django.shortcuts import render
from django.http import HttpResponse
from django.template import Context, loader
##
# Handle 404 Errors
# #param request WSGIRequest list with all HTTP Request
def error404(request):
# 1. Load models for this view
#from idgsupply.models import My404Method
# 2. Generate Content for this view
template = loader.get_template('404.htm')
context = Context({
'message': 'All: %s' % request,
})
# 3. Return Template for this view + Data
return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404)
The secret is in the last line: status=404
Hope it helped!