I'm not sure if this is even possible, but I would like to grab a user's input, pull it into my views.py, manipulate it, and then use that data in other views.
I do not need this data stored in a database, as I won't be referencing it again, and I want to keep this as lightweight as possible.
Currently, I'm trying to pull data from espn's fantasy football site using the python library espnff. My homepage consists of a textfield box and a submit button (Think of google.com).
I have functions set up that will comb through an espn url such as http://games.espn.com/ffl/clubhouse?leagueId=123456 to grab the leagueID, from there I make use of espnff to grab more info on that league.
My ideal use case is someone comes to my site, copies and pastes their league url like the one above, clicks submit and then brings them to https://example.com/{{ leagueID}/ which will display different info that I gather.
I have not found a way to do this without submitting the user input to a model. Is possible to avoid using the database? If so how?
Not sure I understood it right, but what you are trying to do can easily be done without using any models/database or any other kind of persistent storage.
The user submits that information using the form, you grab the URL from the request object in your view, parse the URL to get the league_id and then redirect the user to /{league_id}.
Then on that view, you gather the league_id parameter (from the url), use the library (espnff) to fetch the data with that id and then render the template with that data.
For example, the implementation would be something in these lines:
Make a form in your html template:
<form method="post" action="/">
{% csrf_token %}
<input type="text" name="league_url"/>
<input type="submit" value="Submit" />
</form>
in urls.py:
url(r'^$', index_view, name="index"),
url(r'^(?P<league_id>[0-9]+)$', league_view, name="league_view")
in views.py:
def index_view(request):
if request.method == 'POST':
league_url = request.POST.get('league_url', None)
# Your code to parse the URL and extract the ID
return HttpResponseRedirect('/{}'.format(league_id))
else:
# render form template
def league_view(request, league_id):
# your code here using the league_id
# and render the page with data
(I didn't tested that code, I just wrote it quickly as an example of the flow)
The django documentation describes quite extensively how to do caching with django. You can find the documentation on how to set that up here
Once it's been set up you simply use the cache in the following way
from django.core.cache import cache
cache.set('my_key', 'my_value', 60) # number is in seconds
value = cache.get('my_key')
You can provide dictionaries and such as values. The caching framework will serialize that for you using pickle.
Related
I have a Post model that requires a certain category before being added to the database, and I want the category to be generated automatically. Clicking the addPost button takes you to a different page and so the category will be determined by taking a part of the previous page URL.
Is there a way to get the previous page URL as a string?
I have added my AddPost button here.
<aside class="addPost">
<article>
<form action="/Forum/addPost">
<input type="submit" name="submit" value="Add Post"/>
</form>
</article>
</aside>
You can do that by using request.META['HTTP_REFERER'], but it will exist if only your tab previous page was from your website, else there will be no HTTP_REFERER in META dict. So be careful and make sure that you are using .get() notation instead.
# Returns None if user came from another website
request.META.get('HTTP_REFERER')
Note: I gave this answer when Django 1.10 was an actual release. I'm not working with Django anymore, so I can't tell if this applies to Django 2
You can get the referring URL by using request.META.HTTP_REFERER
More info here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
I can't answer #tryingtolearn comment, but for future people, you can use request.META['HTTP_REFERER']
Instead of adding it to your context, then passing it to the template, you can place it in your template directly with:
Return
A much more reliable method would be to explicitly pass the category in the URL of the Add Post button.
You can get the previous url in "views.py" as shown below:
# "views.py"
from django.shortcuts import render
def test(request):
pre_url = request.META.get('HTTP_REFERER') # Here
return render(request, 'test/index.html')
You can also get the previous url in Django Template as shown below:
# "index.html"
{{ request.META.HTTP_REFERER }}
I have been using django-filters in many of my projects where the search form is on the same page as the list of results and that works just fine, but now im faced by a scenario where i have a search box in my home page and a results page somewhere else, how can i pass the filtered results to the view of my results page?
You could go a couple of different ways.
One idea is to just render a different template if there is search data present in the request.
Seeing as you didn't post any of your own code, we don't know how you have things named or set-up so here is a quick sketch of the kind of thing I mean.
class SomeView(View):
template_name = 'some_view.html'
results_template_name = 'some_view_results.html'
def get(self, request, *args, **kwargs):
if not request.GET.get('q'):
return render(request, self.template_name)
results = SearchFilter(request.GET)
context = {'results': results}
return render(request, self.results_template_name, context)
This would be one of the simplest solutions. You could even get away with using one template and just conditionally dispatch some rendering over whether or not results is in the context.
Another would be to do a full redirect and pass along whatever data you need as kwargs to whatever view you are calling. But that is kind of messy and unnecessary.
The best solution is to wire up a new ResultsView endpoint, move the filtering to that view, and put a reference that URL into the form node on the template. Which would require something like this.
<form method="GET" action="{% url search %}">
<input type="text" id="search" name="q" placeholder="Search">
</form>
Assuming that you have named ResultsView as search in your URL config.
I have a Post model that requires a certain category before being added to the database, and I want the category to be generated automatically. Clicking the addPost button takes you to a different page and so the category will be determined by taking a part of the previous page URL.
Is there a way to get the previous page URL as a string?
I have added my AddPost button here.
<aside class="addPost">
<article>
<form action="/Forum/addPost">
<input type="submit" name="submit" value="Add Post"/>
</form>
</article>
</aside>
You can do that by using request.META['HTTP_REFERER'], but it will exist if only your tab previous page was from your website, else there will be no HTTP_REFERER in META dict. So be careful and make sure that you are using .get() notation instead.
# Returns None if user came from another website
request.META.get('HTTP_REFERER')
Note: I gave this answer when Django 1.10 was an actual release. I'm not working with Django anymore, so I can't tell if this applies to Django 2
You can get the referring URL by using request.META.HTTP_REFERER
More info here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
I can't answer #tryingtolearn comment, but for future people, you can use request.META['HTTP_REFERER']
Instead of adding it to your context, then passing it to the template, you can place it in your template directly with:
Return
A much more reliable method would be to explicitly pass the category in the URL of the Add Post button.
You can get the previous url in "views.py" as shown below:
# "views.py"
from django.shortcuts import render
def test(request):
pre_url = request.META.get('HTTP_REFERER') # Here
return render(request, 'test/index.html')
You can also get the previous url in Django Template as shown below:
# "index.html"
{{ request.META.HTTP_REFERER }}
let's say I have a form like this
<form role="form">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
</form>
then I have a fairly generic route that sorts through a static file
#app.route('/search/properties/', methods=['GET', 'POST'])
def properties_search():
form = request.form
if request.method == 'POST':
properties = CSVReader('properties.csv')
d = [x._asdict() for x in properties.data]
gen = stream_with_context(search_csv(d, form))
return Response(stream_with_context(
stream_template('advanced_search/results.html', form=form, rows=gen)
))
return render_template('advanced_search/advanced.html', form=form)
This will render a page with the results that I am looking for -- and all is well with that. However, on the page, I also want to add the capability to download the data as a CSV.
| download csv | | return to search |
- result 1
- result 2
...
The problem I am having is that, after the post request, I need some way to know what their last form request was on the application.
What is the best way to do this?
There isn't a single "best way" to do this, because what's "best" in your specific case might not suit another scenario. That being said, below are a couple of possible ways (which barely scratch the surface of what you need to do with them to make them production-ready) and there are many, many more.
You really need to research the options yourself here; the scenario you have is not specific to python or flask, it's pretty much a problem for anyone building an HTTP application that needs to remember state!
Render the received form values in hidden inputs
When you are rendering the initial search results. Render the "Download CSV" as the submit input of a form that will post these values back but to the download renderer.
I wouldn't be a huge fan of this as it requires a button and a POST when you are really looking for a GET and if you actually need the password in order to render the results, it's a security problem.
Whilst rendering the initial search results page, render the link for "Download CSV" such that it contains some kind of session ID.
When you receive the initial POST of the form to generate the search results. Take the email and store it in a database table (or some other persistent storage mechanism), recording some kind of generated ID as a result of this operation. You could also save any other search parameters the user submitted, etc.
This ID then becomes a querystring parameter of the link to "Download as CSV". i.e. when your template renders the initial search page, the link ends up like "http://blahblah.com/download?ID=12345"
When the link is requested by the user, lookup the search/ user information from the database based on the querystring ID parameter, and then pass it to whatever template will render the CSV for you.
There are many flavours of this approach and you need to pick the best for your scenario - you can save the search criteria for replay, or save the actual search results, it depends on the nature of the search, how expensive it is to run and whether "download as CSV" has to replay the search OR return the exact results originally obtained, etc), and you will also need to harden it. Don't send raw database IDs - send a hashed/encrypted version of them so that users cannot "guess" download IDs, etc.
I'd recommend this kind of approach because it doesn't require you to return the username/password to the client at all.
Hopefully that will get you thinking :)
I have an HTML file that has a web page design with a single form, for a user to enter his name. I want to create an six entry array for every submission (to later be filled with information on another page)
Is Django the proper utility to use for this? I would like to have the html design file and the python back end processing as separate files. If so, can anyone point me towards a good place to read about integrating HTML and underlying python codes that process HTML submission forms?
Django may be overkill for this. If all you want is a way to link a form to some backend Python code, a micro framework like Flask might be a better choice.
Here is how you do a simple form with Flask:
Create a directory project and inside it, a directory templates
Your template is simple:
{% if name %}
Hello {{ name }}
{% endif %}
<form method="POST">
<input type="text" name="name" value="Enter your name">
<input type="submit">
</form>
Save that as index.html in the templates subdirectory.
Create a file called go.py in the project directory, and in it copy and paste this:
from flask import Flask
from flask import render_template
from flask import request
app = Flask(__name__)
#app.route('/',methods=['POST','GET'])
def process_form():
if request.method == 'POST':
form_input = request.form['name']
return render_template('index.html',name=form_input)
else:
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
Finally from the project directory, type:
python go.py
Open your browser and go to http://localhost:5000/
You can create html form in Django, though you may have to convert the form to a template.
In case this you first time to use django, you may go though the official Django book
Django provides a template system (in which the presentation files are separate from the business logic and the entire system is highly decoupled). The template language is simple (but very powerful) text substitution on top of an existing text file. You can use the Django templates in HTML (full or partial), text, XML, JSON, or nearly any other text-based format.
Django also allows you to hook into another template system, but I don't know a lot about how that works.
Look at the Django template documentation for more information.