Finding difficult to add html to django.shortcuts - django-views

My django Web page will not update after adding html files. The request or response becomes a variable instead of method in render.
Here..
From django.shortcuts import render
def Index(request):
Pass
From the code above, the request becomes a variable and does not receive the html file in pass

Related

How to get url params from the HttpRequest object

Suppose, we have a url path:
path('something/<int:some_param>/test/', views.some_view)
When a user hits this url, django makes an instance of HttpRequest, that will be passed to the some_view view. Is there a way to get the some_param url parameter from the request object outside the some_view code? (for instance, to do some processing that depends on some_param in a custom middleware).
One possible solution is to parse the HttpRequest.path attribute, but is there any prebuilt way to do this?
Django calls your view with the request object and some_param, which you have access to inside views.some_view. Your function will have the following signature:
def some_view(request, some_param):
....
Or:
def some_view(request, **kwargs):
some_param=kwargs.get('some_param', None)
You can then use some_param inside your view to do whatever you need to do with it, save it in a database, put it in a cookie, do calculations with it, get some database data with it, etc. Then once you're done, you need to return a response object. Usually by calling render or TemplateResponse with a template or returning HttpResponse without a template. You render templates providing a context dictionary which you are free to put anything you like into (like some_param), which makes it available to be rendered in your HTML template. That rendered HTML template is then returned as response to your user through the magic of the render function or TemplateResponse class, which ends the view process. I.e. like so:
return TemplateResponse(request, 'template.html', context)
To store some_param in between views, you'll need to save it in the database, store it in the user's session, or use a cookie. Or pass it to the next view inside the url or outside the url via /?param=some_param. Without saying what you need some_param for later on, it's hard to solve your issue.
The one possible solution here is to use the resolve function from django.urls module. It is extremely uselful if you want to access the URL parameters from URL path that is related to a HttpRequest object outside a view function. For example, get the URL params and process them in the custom middleware or other parts of your code.
Example:
from django.urls import resolve
...
func, args, kwargs = resolve(some_request.path)

Django 2.2 'SafeText' object has no attribute 'get'

I am using Django 2.2 in a project. I am rolling an extra lightweight app that allows users to modify the raw HTML used in a template.
This is a cut down example of the function I have written to do that:
def show_page(request):
from django.template import Context, Template
template = Template("<h3>My name is {{ my_name }}.</h3>")
context = Context({"my_name": "Adrian"})
return template.render(context) # <- Django barfs at this line
I get the exception shown in the title:
AttributeError at /show-page 'SafeText' object has no attribute 'get'
How do I resolve this error, so I can display the page correctly?
From Django documentation
Each view you write is responsible for instantiating, populating, and returning an HttpResponse.
Currently you are returning a django.utils.safestring.SafeString which is just a subclassed string
A str subclass that has been specifically marked as "safe" for HTML
output
purposes.
return HttpResponse(template.render(context))
Assuming show_page is a Django view, you should be returning a Response object, not the template string.
Change your view by adding:
from django.http import HttpResponse
return HttpResponse(template.render(context))

Proper way to handle PUT requests Django with forms

I have a web app that allows users to edit previously submitted data.
I'm currently processing PUT requests by manually updating the data.
I would like to use my forms to validate input but I run into the issue of the other required fields.
For instance, if a user updates a date field and I validate it with my form, it errors out as I'm missing other required fields like name, location, etc since the form was designed to be filled out all at once.
What is the best way to use my forms to validate input but conditionally allow required fields if the request is a PUT or POST with model Forms.
If you're getting errors for missing fields you're not using the modelform correctly, sounds like you are not passing it the existing instance to work on.
You need to use a pattern like this:
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
def my_view(request, obj_id):
my_object = get_object_or_404(MyModel, pk=obj_id)
update_form = MyModelForm(instance=my_object, data=request.PUT or None)
if update_form.is_valid():
return HttpResponse(status=204) # empty success response
else:
return render(...) # render update_form.errors somehow
And be sure to include the object id in the url that you send your PUT requests to

Get Django views.py to return and execute javascript

So I'm working with django and file uploads and I need a javascript function to execute after the file has been uploaded.
I have a file upload handler in my views.py which looks like this:
def upload_file(request):
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
for f in request.FILES.getlist('fileAttachments'):
handle_uploaded_file(f)
return HttpJavascriptResponse('parent.Response_OK();')
else:
return HttpResponse("Failed to upload attachment.")
And I found a django snippet from http://djangosnippets.org/snippets/341/ and I put the HttpJavascriptResponse class in my views.py code. It looks as follows:
class HttpJavascriptResponse(HttpResponse):
def __init__(self,content):
HttpResponse.__init__(self,content,mimetype="text/javascript")
However, when I upload a file the browser simple renders "parent.Response_OK();" on the screen instead of actually executing the javascript. And Chrome gives me the warning: "Resource interpreted as Document but transferred with MIME type text/javascript"
Is there anyway to get views.py to execute the script?
A better way is to pass the mime to the HttpResponse Object.
See documentation: https://docs.djangoproject.com/en/3.2/ref/request-response/#django.http.HttpRequest.content_type.
return HttpResponse("parent.Response_OK()", content_type="application/x-javascript")
Note - Some previous versions of Django used mimetype instead of content_type:
return HttpResponse("parent.Response_OK()", mimetype="application/x-javascript")
I believe this will work.
return HttpResponse("<script>parent.Response_OK();</script>")
However, you might think about returning a success (200) status code in this case, and then having some javascript in parent attach to the load event of this child, and branch based on return status code. That way you have a separation of view rendering code and view behavior code.
Chase's solution worked for me, though I need to execute more javascript than I care to put in a python string:
from django.http import HttpResponse
from django.contrib.staticfiles.templatetags import staticfiles
...
return HttpResponse("<script src='{src}'></script>".format(
src = staticfiles.static('/path/to/something.js')))
I ended up here looking for a way to serve a dynamic js file using django.
Here is my solution :
return render(request, 'myscript.js', {'foo':'bar'},
content_type="application/x-javascript")

jQueryUI autocomplete with url as source (am using Django)

I am using Django web-framework for database, page generation etc.
jQueryUI / javascript side of the code
I want to use jQueryUI's autocomplete widget, as my data set will contain about 1,000 entries I wanted to query the database. On the link above it claims you can simply provide a url that returns JSON data:
Autocomplete can be customized to work
with various data sources, by just
specifying the source option. A data
source can be:
* an Array with local data
* a String, specifying a URL
* a Callback
I have taken the default example from the website, which works on my system.
However if I change the following:
$( "#tags" ).autocomplete({
source: availableTags,
});
to
$( "#tags" ).autocomplete({
source: "/search/", // url that provides JSON data
});
the autocomplete functionality doesn't work at all.
I've tried making the url actually return an error (to see if it uses it) and putting in the full url http://localhost:8000/search/, nothing works.
Django part of the code
In url.py
...
(r'^search/$', 'search'),
...
In views.py
from django.http import HttpRequest, HttpResponse
from django.utils import simplejson
...
def search(request):
HttpResponse(simplejson.dumps(["hello", "world"]))
# Will implement proper suggestions when it works.
There must be something wrong with my code and I would greatly appreciate any help you can offer :)
EDIT SOLUTION:
Thanks to #Thierry realised it didn't have a return statement before, have added that so I now looks like so:
def search(request):
output = ["hello", "world"]
return HttpResponse(simplejson.dumps(output))
And it actually works!
(It always seems to be the really small bugs that waste the most of of my time, grrr)
I return my ajax response like the following:
def search(request):
output = ["hello", "world"]
return HttpResponse(output, mimetype="application/javascript")
If you access the url http://localhost:8000/search/, you should see the output. Once you see the output, the autocomplete should work.
There are some changes in json serialization API in later versions
For django 1.6 use
import json
from django.http import HttpResponse
....
return HttpResponse(json.dumps(my_data_dictionary))
For django 1.7+ do it like here