Django Upload From Template - django

I am looking into uploading a file from the html template. I've seen a fair amount of documentation including FileFields, ImageFields etc. However, ideally I do not want to rewrite my code.
Currently, I have a simple form on my template and I would like to have an upload function there, where, an image will be uploaded and stored into my applications media folder and if possible added to a database.
I do know that I've probably taken a long and complex route but if anyone can help it'll be great!
html.py:
<div class="row"> <div class="span1 offset5"> </bR>
<form class="form-horizontal" method="get" action="/add/submit" value="add">
<fieldset> <div class="input">
<div class="inline-inputs">
<label>Ride Name:</label><input type="text" name="name">
<label>Type:</label><input type="text" name="type">
<label>Theme:</label><input type="text" name="theme">
<label>Description:</label><textarea rows="5" name ="description"></textarea>
<label>Author:</label><input type="text" name="author">
<label>Date Released:</label>
<div id="datetimepicker" class="input-append date">
<input type="text" name="date"></input>
<span class="add-on">
<i data-time-icon="icon-time" data-date-icon="icon-calendar"></i>
</span>
</div>
<label>Thread:</label><input type="text" name="thread">
<label>Video</label><textarea rows="2" name ="video"></textarea>
<br><br>
<input class="btn btn-primary" type="submit" value="Add" />
</div> </div>
</fieldset>
</form>
</div> </div>
Currently my Views.py just takes the entered data and inserts it into a database. I want to add the ability for a file to be uploaded:
def Ride_Add_Submit(request):
name = request.GET['name']
type = request.GET['type']
theme = request.GET['theme']
description = request.GET['description']
author = request.GET['author']
releasedate=request.GET['date']
video=request.GET['video']
thread=request.GET['thread']
entry = RollerCoaster(name=name, type=type, theme=theme, description=description, releasedate=releasedate, author=author, video=video, thread=thread)
entry.save()
return TemplateResponse(request, 'Ride_Add.html')

I don't understand why you keep talking about the template here, the template has nothing whatsoever to do with anything. The handling of the upload, like all logic, is done in the view.
The file upload overview still has all the information you need. You can ignore the parts about the Django form and checking if it's valid, and simply pass the file object to your upload handling function, which that page also explains.
However you will need to change your template so that the form element uses POST instead of GET (which is almost certainly a good idea anyway), and use enctype="multipart/form-data" as also described on that page.
Finally, I really would advise you to rewrite your code to use ModelForms. Not only would it make your code much simpler, it would also do things like validate the entry to make sure all the required fields are present and are of the right types, and so on - as well as output valid HTML (for instance, you're missing for attributes in your label tags).

Related

How can I get custom form field value from within Django Admin's response_change?

I've added a custom functionality to a model by overriding change_form.html. Basically, I'm letting users change the objects of a model if these changes were approved by the admin. I added two buttons, named accept-suggestion and decline-suggestion and I intend to handle the custom functionality through response_change method:
def response_change(self, request, obj):
if "decline-suggestion" in request.POST:
# do stuff...
if "accept-suggestion" in request.POST:
# do stuff...
Both buttons will send an e-mail to the user saying if the suggestion was declined or approaved. So far so good. The problem is that I want to add the possibility to the admin write a brief justification explaining why the suggestion was declined. So I changed change_form.html again.
<div class="submit-row">
<div class="float-left">
<a class="decline-button-outlined accordion" type="button" href="#">DECLINE SUGGESTION</a>
</div>
<div class="float-right">
<input class="accept-button" type="submit" name="accept-suggestion" value="ACEITAR SUGESTÃO">
</div>
</div>
<div class="additional-infos">
<fieldset class="module aligned">
<div class="form-row">
<label for="decline-reasons">Reasons for rejection:</label>
<textarea
placeholder="If you find necessary, provide information on the reasons that led to the rejection of the suggestion"
id="decline-reasons" class="vLargeTextField" rows="5"></textarea>
</div>
<div class="submit-row">
<div class="float-right">
<input class="decline-button" type="submit" name="decline-suggestion" value="DECLINE">
</div>
</div>
</fieldset>
</div>
Is this the best approach? If so, how can I get the value of the <textarea> above from within response_change? If not, what would you suggest?
Thank you very much!
If you add a name to your <textarea> you will be able to retrieve the contents on the server side. Without a name, the data is not being sent to the server (Django).
So something like this:
<textarea
placeholder="If you find necessary, provide information on the reasons that led to the rejection of the suggestion"
id="decline-reasons" name="decline-reasons" class="vLargeTextField" rows="5"></textarea>
Should allow you to retrieve the text on the Django side with request.POST["decline-reasons"].

Django: how to retrieve a form search parameters in a django generic listView

how to retrieve a form search parameters in a django generic listView. My url is:
url(r'postsearch$', views.PostsList.as_view(), name='postsearch'),
My generic listview is:
class PostsList(generic.ListView):
model = Post
template_name = 'posts/post_list.html'
def get_queryset(self):
localisation = #how to get location
discipline = #how to get discipline
return Post.objects.filter(.......)
and my form is:
<form class="form-inline text-center" action="{% url 'posts:postsearch' %}" id="form-searchLessons" method="get">
<div class="form-group">
<input type="text" class="form-control" id="typeCours" list="matieres" placeholder="Matieres: e.g. Math, Physique,.." name="discipline">
<datalist id="matieres">
<option value="value1">
<option value="value2">
</datalist>
</div>
<div class="form-group">
<input type="text" class="form-control" id="Localisation" placeholder="Lieu: Bousaada, Douaouda,.."
name="localisation" onFocus="geolocate()">
</div>
<button type="submit" class="btn btn-default" id="btn-getLessons">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span> Trouver !
</button>
</form>
I want to get the Posts by applying a filter according to the lacalisation and matieres introduced in the search fields (in the form)
You can add the search terms to your url regular expression.
url(r'postsearch/(?P<localisation>\w+)/(?P<descipline>\w+)/$', views.PostsList.as_view(), name='postsearch'),
(Note, mind the trailing slash)
In your get_queryset method you can use those given url parameters
def get_queryset(self):
localisation = self.kwargs['localisation'] or None
discipline = self.kwargs['discipline'] or None
filters = {}
if localisation:
filters.update(localisation: localisation)
if discipline:
filters.update(discipline: discipline)
return Post.objects.filter(**filters)
Eventually you should relocate getting the parameters outside your get_queryset, but that is up to you.
I'm not sure about the security risks doing it this way. Anyone having more information about the security risks during this operation, please share.
I build a library that can help you to solve this problem, you just have to put in the searchable_fields the attributes you want to filter and it will take care of the rest.
https://github.com/SchroterQuentin/django-search-listview

Adding extra HTML tags and attributes to Django crispy-forms fields

I'm using django-crispy-forms with Bootstrap and I'm wanting to add some extra HTML inside the HTML rendered for the a single field.
For example if my form contains,
recipients = forms.CharField(label='To',widget=forms.TextInput(
attrs={'placeholder': 'Enter phone number, contact or group (add as many as you like)'}))
Then the normal rendering (using the Bootstrap templates) is,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
</div>
What I want to do is have some extra HTML appear just before the final closing div. So it would look like,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
<div class="controls-aside">
<button type="button" class="btn">Address Book</button>
<button type="button" class="btn">Add Contact</button>
</div>
</div>
I know that I can replace the existing template for this field with a custom template but I want to be able to re-use their template without doing a copy/paste since that makes it not very maintainable.
So what is the best way to implement this? I also want to add an extra class to the label if anyone can suggest how to do it?
For completeness, but not for your case: even after layout creation, Layout.wrap('recipients', Div) will work if one only needs to wrap a control into an additional Div.
About adding HTML inside the layout. Last hour I needed a very custom HTML, so did this:
(formatting)
i = self.helper.layout.fields.index('guest_email')
self.helper.layout.insert(
i+1,
HTML('{}'.format(
reverse_lazy('invite_guests'),
_('Invite to a party'))
))
I came here googling for a HTMLWrapper class example for Crispy Forms, so that I could do a prettier thing instead:
self.helper['guest_email'].wrap(HTMLWrapper(
'guest_email',
before='',
after='{}'.format(href, title))
If I end up creating one, I'll get back and post it.
For me it worked that way:
from crispy_forms.layout import Field, HTML
self.helper["some_field_name"].wrap(Field, HTML("<p>Example</p>"))
The benefit of using HTML is that it also gives you the possibility to use context variables.

Django Form Submission Error

I have this recurring problem with form submission in Django, and the frustrating part is that I'm not sure how to interpret what's happening. Essentially I have different pages with form submissions on them. Some of them work as following
localhost/page/formpage--> localhost/page/receivingpage
which is what I expect. Othertimes, it goes to a page like this
localhost/page/formpage--> localhost/page/formpage/recevingpage
and the screen shows a blank form page, which is not what I expect. I'm not sure how to interpret this, and I'm not sure where to look for errors in my code. I think I don't fully understand what's going on when I submit a form, how does it generate a URL after I press 'submit'?
Edit: here is my html form:
<!DOCTYPE HTML>
<html>
<div>
<p>Entry Form</p>
<form action= "user" method="post" >
{% csrf_token %}
<p><label for="id_username">Username:</label>
<input id="id_username" type="text" name="username"" /></p>
<p><label for="id_password">Password</label>
<input type="password" name="password" id="id_password" /></p>
<input type="submit" value="Submit" />
</form>
</div>
</html>
I suspect it isn't the form, I have it on another application and it works... the trouble is I don't know if it's the view, the template, or w/e, so I'll update the post with info as people request it.
I'd recommend putting in an action using the url template tag. With that, you will know for certain where the form is going to end up:
<form action="{% url 'user-url-name' %}" method="post">
The url tag will be an absolute url. Without this, you're going to end up at a relative url depending on where in your application the user submits the form, which can be quite confusing during development and not entirely correct.
Using {% url %} tag is the proper way to do. Your problem can also be solved by adding a forward slash / to the action attribute like this:
<form action="/user" method="post" >
Hope this helps!

Django templating and adding elements to template

I do a lot of re-rendering templates (adding elements, removing elements) using AJAX. Is there an easier way to do this where I could define certain elements ahead of time and pass in a Javascript associative array and it would return the HTML for me? I have heard suggestions for Handlebars, but I heard that it conflicts with Django's templating system.
An example of this is:
<div id="overlay"></div>
<div id="add-action-box" class="lightbox">
<a class="close" href="#">X</a>
<h2>Add Goal</h2>
<form class="lightbox-form" id="add-action-form">
<div class="lightbox-form-element">
<label>Goal</label>
<input type="text" />
</div>
<div class="lightbox-form-element">
<label>Deadline</label>
<input type="text" />
</div>
<div class="lightbox-form-element">
<input type="submit" value="Add Goal" />
</div>
</form>
</div>
I want to be able to define the above HTML elsewhere and allow Jquery to append the above to another element. I don't want to type in the above and delete all of the newlines, add \, put quotes around everything, etc. It makes it harder to read.
It is frustrating to edit HTML when it is on the same line like this:
$("body").append('<div id="add-action-box" class="lightbox"><a class="close" href="#">X</a><h2>Add Goal</h2>')
Have you considering using something similar to jQuery Templates. They are no longer maintained and the project has been picked up by jQuery UI. More details can be found here. I usually find them helpful in situations like yours.