Referencing external URLs - django

I'm trying to find a way to write a proper view in Django that references an external URL.
For examples, typically I could write a simple view as follows:
from django.http import HttpResponse
def my_view(request):
if True:
return HttpResponse('<h1 >hello world</h1 >')
Alternately, we can we can reference a template with render_to_response. How do we reference an external URL such as "google" for example?

You can use the HttpResponseRedirect to redirect the user to the provided url.
from django.http import HttpResponseRedirect
def my_view(request):
if True:
return HttpResponseRedirect('http://stackoverflow.com')

Judging from your comments on the first answer, here is what I think is your problem:
You want to load a static JSON file, and you wish to know how to do this.
Okay, so if this said file is on your server, then you are going to have to use the static url tag. If you want to load this JSON file from a place that is not on your server, just put in the full web address, like so: http://www.google.com
Now, if this said JSON file is on your server, then it is a separate issue. In this case you are dealing with a static file. And here is a nice place where you can learn about static files.
If however, this JSON file changes, then you have a different problem entirely.

You're still not thinking on trends of what the browser can do. The browser can't access things on your server's filesystem, of course. It can only load content that is served up by something, whether it's Django, your static media server, or an external server.
But I don't understand why you want Django to redirect to this content. Either you load the JSON directly from the Javascript, or you load it from the filesystem within your view and pass it to your template so it's included in the page content already.

Related

Django, render with link or remove template dirs when render in view

hai i am newbie in django and sorry for grammar mistake
first i have some project to upload file extension .html to AWS S3, so in views.py i want to render a link i've already uploaded to AWS S3. ex: render(request, 'somelink.com', context) , it possible? or any other solution? and also i want to send context parameters
why i not using media_url upload to local? cause i have limited disk, and other problem when i do production i cant load media_url, ignore this case, cause i already try many solution
Assuming that you want to render it server side, you will need to fetch the template (the .html file) and render it.
You can do it using the requests library to fetch the url template. And the Django template render engine to render the context: https://docs.djangoproject.com/en/4.1/ref/templates/api/#rendering-a-context
import requests
from django.template import Template, Context
template = requests.get('somelink.com').content
t = Template(template)
c = Context(context)
return HttpResponse(t.render(c))
Notes:
It can worse the response time from your server.
As you are concerned about space, you can try to use a front-end solution to render data from your server via API.
Hope it can help you.

Serve static HTML in Django

I’m pretty new to Django so forgive me if this is something I shouldn’t even consider, but I’d like my app to be able to link to a large number of static HTML pages (enough that creating URL paths to each one would be unreasonable) and there would constantly be more being uploaded (by me via FTP).
I’ve got this working on the the development server by adding the path to those HTML files to my STATICFILES_DIRS [] but that doesn’t seem to work when I push my code to production.
I tried setting up a STATIC_ROOT and running collectstatic but that didn’t help, and I’m also worried that even if I got that working, I would have to run collectstatic each time I uploaded new files.
So my question is, is this even reasonable? Should I just avoid hosting these static HTML files alongside my project and leave them where they are now, on a separate server under a separate domain?
The only reason I wanted to host them together initially is because along with the static HTML files, there is an SQL LITE database that my Django app displays data from (this is the whole purpose of my app). However, I could just implement another method of getting that SQL LITE file like using ftlib. Note that I don’t need that database to connect to Django at all - I just needs to read data from it.
You don't need to write urls for every page. You can "capture" the requested page name from the url and render the page according to its value.
# urls.py
url(r'^page/(?P<page_name>\w+)/$', my_view)
# views.py
import os
from django.http import HttpResponse, Http404
FTP_UPLOAD_DIR = '/path/to/directory/where/you/upload/files/'
def my_view(request, page_name):
# check if requested page exists
if os.path.exists(FTP_UPLOAD_DIR + page_name):
# if yes, then serve the page
with open(FTP_UPLOAD_DIR + page_name) as f:
response = HttpResponse(f.read())
return response
else:
raise Http404
Above, we are reading the file directly from the upload folder, so there's no need for you to run collectstatic.

How to tell Django to put media (pdf) files urls in sitemap.xml?

I've put static views and model views in my Django generated sitemap.xml file but i do not know how to tell Django to put all of the media files in to it? I have a hundred of PDF files with seo friendly links and i want them in my sitemap.xml, but as they are not in correlation with any of my models i don't know how to manage this?
EDIT: I almost forgot one important thing - my media (pdf) files are served through CloudFront so even if i manage somehow to list them in my Django Sitemap.xml i'll have additional problem because they have 'something.cloudfront.com' in their url's and not on my web site's url 'example.com'.
Is this even possible to solve? How does this reflect on SEO?
SOLVED:
#kb, thanks for a great answer! I've used RewriteRule in my htaccess as you suggested in the first part of your answer, and it works fine.
As of second part, instead of creating model for my media files (which would work just fine, but only downside would be manual adding of every new pdf file)
i decided to add some lines to my items() method so i could list bucket content and filter pdf files. With that i can have all of my files up-to-date all the time, easily:
#sitemap.py
import boto
from boto.s3.key import Key
from boto.s3.connection import S3Connection
import re
def items(self):
AWS_ACCESS_KEY_ID = #'my_access_key_number'
AWS_SECRET_ACCESS_KEY = #'my_secret_access_key'
Bucketname = #'my_bucket_name'
conn = boto.s3.connect_to_region('eu-central-1', aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, is_secure=False, calling_format = boto.s3.connection.OrdinaryCallingFormat())
bucket = conn.get_bucket(Bucketname)
new_list = []
regex = re.compile(r'bucketsubfolder/media.*\.pdf$', re.I) #i hold my media files in bucketsubfolder so url is for example somedomain.cloudfront.net/bucketsubfolder/media/somefile.pdf
for item in bucket.list():
if regex.match(item.name):
new_list.append(item.name)
return new_list
You are not allowed to use external urls in your sitemap (or rather, they won't have the desired effect being indexed by Google as part of your site content).
I think your best option is to dedicate a path on your site like /hosted/pdf/xxxx.pdf that rewrites everything to cloudfront.com/pdf/xxxx.pdf or similar using mod_rewrite/location patterns/regex.
That way you can use a local site URL in your sitemap but still have the browser sent to the cloudfront served content directly, I think this might even be a good use of the 302 HTTP status code.
In the Sitemap class there is an items() method that returns what is to be included in the sitemap.xml, and you could create your own class that extends it and adds additional data.
You can either manually add the data hardcoded in the method but I think the preferred option is to create a Model that represents each remote hosted file and that contains the information necessary to output it in the sitemap. (This also lets you add properties such as visibility on a per file basis and lets you manage it via admin assuming you set up a ModelAdmin for it.)
I think you might be able do something similar to what they show in http://docs.djangoproject.com/en/1.9/ref/contrib/sitemaps with the BlogSitemap class that extends Sitemap. Be sure to check the heading "Sitemap for static views" on that page as well.
My suggestion is that you chose the model approach to represent the files, so you have your hosted PDFs (or other CDN content) as a model called StaticHostedFile or similar and you iterate through all of them in the items() section. It does require you to index all the current PDFs to create models for them as well as create a new model whenever a new PDF is added (but that could be automated).
It can be good to know that you can add "includes" in a sitemap.xml so you might be able to split the site content into two sitemaps (content+pdfs) and include both in sitemap.xml, for instance:
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>http://www.example.com/original_sitemap.xml</loc>
<lastmod>2016-07-12T09:12Z</lastmod>
</sitemap>
<sitemap>
<loc>http://www.example.com/pdf_sitemap.xml</loc>
<lastmod>2016-07-15T08:55Z</lastmod>
</sitemap>
</sitemapindex>
This still requires local URLs and rewrites as per above though, but it can be a nifty trick for when you have several separate sitemaps to combine. (For instance if running a Django site under one subdir and a Wordpress site under another or whatnot.)

Importing HTML in Django

I have imported an HTML file which displays fine --
def index(request):
html = open('index.html')
return HttpResponse(html)
However, the CSS import and image references are not working (even though the files are there and it works when I test the file outside of Django). What do I need to do so that the imports/references within the HTML work? Thank you.
Not sure if you've read through Django's docs, but I think what you probably want is this:
from django.shortcuts import render_to_response
def index(request):
return render_to_response('index.html')
EDIT: Take a read through this: http://docs.djangoproject.com/en/dev/intro/tutorial03/
I have a feeling that your problem may be related to media and/or static file hosting. If you view the page source and click on your links, do they go to Django's 404? How are you hosting your files?
If you are just working on development on your local machine take a look at the docs for static file hosting.
Also- if there isn't any logic in your view, other than html rendering, check out direct_to_teplate generic view which allows you to go straight from your urls.py to a template without writing a view.
Good luck!

Redirecting to a page

I am facing a problem: I want to give a link in my change form that will redirect to a page which may be simple php page also or any page, in that page I want to perform some db queries and display them. I also wan to pass id on click. Is it possible?
In my view.py I wrote:
from django.shortcuts import render_to_response
from django.template import RequestContext
def MyClass(self,id,request):
return render_to_response('admin/custom_change_form.html')#my template location
My model and admin files are simple.
To send to a file directly, use direct_to_template(). You can pass anything in the url that you like - just give the information to your template, and write it in the url. After all, Django doesn't require url helpers.
I sense that whatever you're trying to do is some god-awful hackish thing that would be much better served by doing it all in Django.
You will need to override your change form for that model and display whatever you would like. But that is making the assumption you are talking about the contrib admin within Django.
Realistically you have not provided sufficient information for anyone to accurately answer your question.