I looked at this question:
Uploading multiple files with Django
but it did not seem to help as I have issues regarding it:
I don't want to deal with flash sessions using SWF Upload and Uploadify because I need to do uploads that only authenticated users can do.
newforms are for older versions of django, I am using 1.3
Using Django, how can I have this HTML form structure:
<form enctype="multipart/form-data" action="." method="post">
<label for="id_image_1">Image 1</label>
<input type="file" name="image[]" id="id_image_1" />
<label for="id_image_2">Image 2</label>
<input type="file" name="image[]" id="id_image_2" />
</form>
and handle it using a view?
If you have a fixed number of filefields, you could simply define a form with enough filefields, or add filefields programatically in a form's constructor. See the Django docs on File Uploads.
If you want some sort of dynamic functionality (a la gmail's "add another file"), then you could define a formset using a form with a single filefield. Display a single form initially and when you want to add another, use a little javascript to produce the new form and update the formset's management form. There are a number of snippets floating around to help you do this, though they may need some tweaking. See the Django docs on File Uploads and Formsets.
Another option may be to use a custom widget and field, though I have not reviewed or tried this.
On the off-chance you aren't aware, the name="image[]" scheme is PHP specific and has no special meaning in other languages, unless you reimplement it.
newforms is what the current forms were called before 1.0. Furthermore, if you got your form validated, http://docs.djangoproject.com/en/dev/topics/http/file-uploads/, you'll have your files as a list (tuple, probably, but sequence anyway) in request.FILES['image'], so just do:
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
for f in request.FILES['image']:
handle_uploaded_file(f)
You'll have to write handle_uploaded_file yourself, the URL explains how
Related
I'm very new to Django, so please forgive me if I'm using some of the terminology incorrectly.
In one of my templates, I'm trying to use a form that has multiple input fields. In this specific case, the value of the two fields will always be the same (userName and userID will always match if they are at this template) and I do not want to alter the form itself. For this reason, I want to customize the form in this template so that there is only one place for the user to provide input, and use that in both fields of the form so that the user doesn't need to type in their ID twice.
This is the code fragment I'm currently using:
<form method="post">
{% csrf_token %}
<label>ID:</label>
<input type="text" name="userID" id="userID" placeholder="Type your ID number here.">
<input type="hidden" name="userName" id="userName" value=userID>
<button type="submit">Login</button>
</form>
I know that the issue is with the "value=userID" bit, but I've been searching and I can't figure out how to use information from one input field in multiple places. How do I take the userID and submit it as the userName without requiring the user to input it twice?
You don't need to provide the same input two times to use it in your back-end. You can use the same value in the back-end.
So let's say you have want the userName in your back-end to be same as userID value:
def login_page(request):
if request.method == 'POST':
userID = request.POST.get('userID')
userName = userID
That was the basic idea, if you are using class based views with Django's forms, you should place this code in the form_valid method.
New Django user here.
I am trying to restrict access to Django's success_url() upon GET requests. I realize I am not the first to ask this question, however, I am specifically trying to achieve this in conjunction with Django's generic class-based views. Generic views seem cleaner, faster, and more idiomatic. I want to use them as much as possible unless they are absolutely unfit for the job.
Basically, I am creating a simple contact form for non-users who only want to send me a message without creating an account. I've created a contact app to handle these types of contacts. I've created a ModelForm, which I am rendering with a contact.html with Django's FormView. After a person submits the form, they will receive a cool looking thank you message, rendered with a thanks.html, which has its own url.
But I only want them to see the thank you message if they POST the contact form. Currently, you can go on my site and type '/contact/thanks/', and my thanks.html will be rendered whether you've submitted a form or not. Django's success_url apparently defaults to a GET request.
Here's my view:
class MyContact(FormView):
template_name = 'contact.html'
form_class = ContactForm
success_url = 'thanks'
Here's my form:
ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['email_address', 'message_body']
Here's the html form in contact.html:
<form action="" method="POST">{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="send btn btn-secondary">Send Message</button>
</form>
My first thought was to decorate my contact app url with a require_POST() decorator like this:
urlpatterns = [
url(r'^thanks/$', require_POST(views.ThanksPageView.as_view()), name='thanks'),
]
This doesn't work because Django's success_url() defaults to a GET request.
What is the most idiomatic way to approach this? Since Django is a 'batteries included' framework, I do not want to use 'duck-tape', meaning I do not want implement any ad-hoc logic in my views or urls.
Sorry if I've missed anything in the docs or questions archive.
Since you're asking for a idiomatic approach, I would consider the messages framework and specifically the SuccessMessageMixin. This would allow you to add a success message to e.g. the contact form itself and the url-pattern for the /thanks/ page would not be necessary.
How to save a file, uploaded from a form to a local directory without using model? Also the form is being posted using ajax, so how do I render the file information from the html file?
Create an HTML form with
<form method="post" enctype="multipart/form-data" action="your_view_name">
<input name="myfile" type="file" />
</form>
Use AJAX to post the file. If you're using jQuery, see this link on how to post stuff
http://api.jquery.com/jquery.post/
In the view, use request.FILES to access the uploaded file. Use whatever Python APIs you have to save the file to the disk.
I've installed Django-Photologue and I can upload files and create galleries in my Django admin site. I've been searching the documentation below for examples on how to create a photo upload form so my users can create a gallery on my site but can't find a simple example to get me started. I've also setup their example application but it wasn't very helpful in terms of how to upload and create Galleries by POSTing from Views/Templates.
Docs:
https://django-photologue.readthedocs.org/en/2.7/
https://code.google.com/p/django-photologue/
Can someone please provide a simple example of how I can create an upload form for submitting photos and creating a gallery for use with Django-Photologue ( not using just admin site)?
This is quite simple, Photologue has all the relevant logic inside its models.
For example to setup photo upload, you can use CBV:
urls.py
from django.views.generic import CreateView
from photologue.models import Photo
urlpatterns = patterns('',
url(r'^photologue/photo/add/$', CreateView.as_view(model=Photo),
name='add-photo'),
(r'^photologue/', include('photologue.urls')),
...
In your template, remember to set enctype attribute, to handle files.
templates/photologue/photo_form.html
<form action="" method="post" accept-charset="utf-8" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Submit">
</form>
That's basically all you need.. as you can see, we don't use any custom logic, everything is encapsulated inside Photo model and the CBV does the rest.
The same applies to Gallery, just replace the model with Gallery and you're good to go.
Obviously if you need some customization, you can do it as well, but that's outside the scope, since you didn't specify what use case you need to handle.
One thing missing from the answer above is you have to set the success_url in the CreateView.as_view. For example: CreateView.as_view(model=Photo, success_url='/')
Otherwise you'll receive a ImproperlyConfigured error.
Say you already have a complex HTML form, possible from a designer, front end dev, etc. Is it common practice to not use dynamic forms (based on a Django form) for complicated forms?
I want to do something like this:
1.) Create custom HTML form.
2.) Catch form data through POST request, put it in an object/dictionary.
3.) Do some manipulations with that data to get it in a format acceptable by a Django form.
4.) Pass the manipulated data in to a form object, validate it, etc...
What is a clear solution to this problem? Should I be using Django's dynamic forms for everything? If not - how do I implement the above?
EDIT:
Part of my question has to do with using the forms ONLY for validation. I don't think I made this clear. Here is what I'm trying to do:
template.html
<form method="post">
{% csrf_token %}
<input class="foo" name="bar" type="text" value=""/>
<!-- Some more fields, not rendered through Django form -->
<button type="submit">Create Object</button>
</form>
As you can see, other than the csrf_token there is no Django code here. What I am trying to do in my view is catch the data in the POST in my view, make some changes to the data, then try to bind the new data to a form (not sure if it's possible):
views.py
def my_view(request):
# Some GET code
if request.method == 'POST':
form = ImportedForm(request.POST)
form.data['foo'] = "newValue"
# Now after changing the data, validate it...
If the form and model match nicely then I'll take advantage of the ModelForm functionality.
But most of the time it is not so tidy so, most typically, I do things in about this order:
create a django form with all the field definitions
create django GET view to serve the empty form
create an html template which serves the default html/form
test the blank form
create the POST routine to call validation and reserve the validated (erroneous) form
modify the django form to validate the fields
modify the html form to serve the error messages
test the validation and error messages
modify the POST routine to handle a valid form and do whatever it should do as a result (might involve a redirect and 'thanks' view/template)
Test the whole lot
let the designer loose on the templates
In truth the designer will be involved at some points earlier along the way but in theory I just get it all to work as a "white" then add all the fancy stuff after. That includes javascript validation (ie after all the above).
I ended up doing something like this. It is ugly, and may not be the proper way to do it, but it works...
if request.method == 'POST':
try:
# Create dictionary from POST data
data = {
'foo': request.POST['foo'],
'foobar': request.POST['foobar'],
}
except:
# Handle exceptions
form = ImportedForm(data)
if form.is_valid:
# Continue to validate and save