How can I set myfile form field as Dropzone.js upload area?
forms.py
class TestForm(forms.Form):
title = forms.CharField(required=True)
myfile = FileField()
views.py
class ExampleView(FormView):
template_name = 'test.html'
form_class = TestForm
success_url = '/thanks/'
def form_valid(self, form):
print form.cleaned_data['title']
print form.cleaned_data['file']
return super(ExampleView, self).form_valid(form)
test.html
<form method="post" action="/test-form/">
<input type="text" name="title" id="id_title">
<input type="submit" value="Save">
</form>
Well, I just checked the dropzone website, and there are a few different ways.
One would be by configuring the paramName option: http://www.dropzonejs.com/#config-paramName
But it looks like you could just add the file field, e.g., <input type="file" name="myfile" />
You'll need to add class="dropzone" to the form.
Related
So i've been working on a project for a while, in which I use the Django default User Instance but with additional attributes, which are stored in a "Profile"-Model. So right now i have an assigned company, and an Profile-Image for the user in the Profile Model.
Now i have a detailview to edit the user's attributes (firstname, username, email, etc.). i used generic.DetailView for this View. But this is only working for the Attributes in the User-Model from Django. How can I also change Attributes in the Profile Model when editing the User?
This is my Edit-View:
class ProfileUpdateView(LoginRequiredMixin, UpdateView):
model = User
fields = ['username', 'email', 'first_name', 'last_name']
template_name = 'inventory/edit_forms/update_profile.html'
success_url = '/profile'
login_url = '/accounts/login'
redirect_field_name = 'redirect_to'
def form_valid(self, form):
profile = Profile.objects.get(user=self.request.user)
profile.img = self.request.POST.get('profile_img')
profile.save()
return super().form_valid(form)
def get_object(self):
return User.objects.get(pk = self.request.user.id)
This is my HTML:
<form class="edit_object" action="" method="post" enctype='multipart/form-data' class="form-group">
<div style="width: 20%; margin-bottom: 1rem;">
<label>Profile Image</label>
<input name="profile_img" type="file" accept="image/png, image/gif, image/jpeg">
</div>
{% csrf_token %}
{{form|crispy}}
<input type="submit" value="Submit" class="btn action_btn">
</form>
As you see i already tried using a external Input field and setting the image like that. But after submitting, the img attribute in the Profile-Model is just set null and I don't know why.
What did I miss?
if you want to go this way use request. FILES
I was making my own forms for CreateView and UpdateView with my html file because I don't want to display the form like this {{form.as_p}}.
forms.py
from django import forms
from .models import Post
class PostCreationForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'cover', 'text',)
widgets = {
'title': forms.TextInput(attrs={'class': 'title'}),
'cover': forms.FileInput(attrs={'class': 'image'}),
'text': forms.TextInput(attrs={'class': 'text'})
}
class PostDeleteForm(forms.ModelForm):
class Meta:
model = Post
fields = ('__all__')
views.py
from django.shortcuts import reverse
from django.http import HttpResponseRedirect
from django.views import generic
from .models import Post
from .forms import PostCreationForm, PostDeleteForm
class PostListView(generic.ListView):
model = Post
context_object_view = 'post_list'
template_name = 'forum/post_list.html'
class PostDetailView(generic.DetailView):
model = Post
context_object_view = 'post'
template_name = 'forum/post_detail.html'
class PostCreateView(generic.CreateView):
model = Post
form_class = PostCreationForm
template_name = 'forum/post_create.html'
def form_valid(self, form):
if form.is_valid():
response = form.save(commit = False)
response.author = self.request.user
response.save()
return HttpResponseRedirect(reverse('post_detail', args=[str(response.id)]))
class PostUpdateView(generic.UpdateView):
model = Post
context_object_view = 'post'
form_class = PostCreationForm
template_name = 'forum/post_edit.html'
def get_post(self, pk):
return get_object_or_404(Post, pk=pk)
def form_valid(self, form):
if form.is_valid():
response = form.save(commit = False)
response.save()
return HttpResponseRedirect(reverse('post_detail', args=[str(response.id)]))
class PostDeleteView(generic.DeleteView):
model = Post
context_object_view = 'post'
form_class = PostDeleteForm
template_name = 'forum/post_delete.html'
success_url = '/'
def get_post(self, pk):
return get_object_or_404(Post, pk=pk)
post_create.html
{% extends '_base.html' %}
{% block css %}
{% load static %}
<link rel="stylesheet" href="{% static 'css/post_create.css' %}">
{% endblock css %}
{% block title %}Questions{% endblock title %}
{% block content %}
<h1 class="m-title">New Post</h1>
<div class="form">
<form action="" method="post" enctype="multipart/form-data" id='postform'>
{% csrf_token %}
<p class="n-title"><label for="id_title">Title: </label></p>
<input id="id_title" type="text" name="title" class="title" maxlength="40" required>
<p class="n-image"><label for="id_cover">Image: </label></p>
<input id="id_cover" type="file" name="cover" class="image" required>
<p class="n-text"><label for="id_text">Text: </label></p>
<textarea id="id_text" placeholder="Enter your text here" name="text" class="text" form='postform' required></textarea>
<button class="btn btn-success" id="button" type="submit">Submit</button>
</form>
</div>
{% endblock content %}
And I also wanted to do for the UpdateView, but I don't know how to make the input fields display the current value of the post (title, text). The html file is the same as for CreateView. How do I make the input display the current value of the post that is being modified?
You probably don't want to be manually writing the html for the form like that.
If you must, you can pass in value like:
<input id="id_title" type="text" name="title" class="title" maxlength="40" value="{{ form.title.value }}" required>
Better would be to render the field using django so that your form field attributes like maxlength and required match your form class specification. For example, this will create the input for your title field:
{{ form.title }}
If you want more flexibility in styling look at crispy-forms or my preference floppyforms
I'm using django with forms. And on every one of them django add <tr> & <td> before the different inputs.
Example:
forms.py
class LoginForm(forms.Form):
username = forms.CharField(label='username', max_length=50)
password = forms.CharField(label='password', widget=forms.PasswordInput, max_length=100)
views.py:
class Login(View):
def get(self, request):
form = LoginForm()
return render(request, 'login.html', {'form': form})
In the html file i simply import the form via
{{ form | linebreaks }}
But now the given html code looks like this:
<form method="post" action="/">
<input type="hidden" name="csrfmiddlewaretoken" value="*csrftoken*">
<p><tr><th><label for="id_username">username:</label></th><td><input type="text" name="username" maxlength="50" required id="id_username"></td></tr><br><tr><th><label for="id_password">password:</label></th><td><input type="password" name="password" maxlength="100" required id="id_password"></td></tr></p>
<br>
<button class="button" type="submit">Login</button>
</form>
But why does django do this? Can't it simply just use the input tags?
try this :
{{form.as_p|linebreaks}}
instead of :
{{form|linebreaks}}
I am new to Django and what I want to do is quite simple, but I am confused:
I want to create a Django form (simple form not ModelForm) and write a function which takes data from this form like username and password(which user types in front-end) and print it in console.
i have tried adding a form to froms.py but am a bit confused regarding the view part
You should create a view that extends FormView:
from myapp.forms import YourForm
from django.views.generic.edit import FormView
class YourView(FormView):
template_name = 'template.html'
form_class = YourForm
success_url = '/thanks/'
def form_valid(self, form):
print(form.cleaned_data)
And make sure you have a template that will display the form:
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Send message" />
</form>
And when you submit the form, it should print the form's data in your console!
I have form with one input for email and two submit buttons to subscribe and unsubscribe from newsletter:
<form action="" method="post">
{{ form_newsletter }}
<input type="submit" name="newsletter_sub" value="Subscribe" />
<input type="submit" name="newsletter_unsub" value="Unsubscribe" />
</form>
I have also class form:
class NewsletterForm(forms.ModelForm):
class Meta:
model = Newsletter
fields = ('email',)
I must write my own clean_email method and I need to know by which button was form submited. But the value of submit buttons aren't in self.cleaned_data dictionary.
Could I get values of buttons otherwise?
Eg:
if 'newsletter_sub' in request.POST:
# do subscribe
elif 'newsletter_unsub' in request.POST:
# do unsubscribe
You can use self.data in the clean_email method to access the POST data before validation. It should contain a key called newsletter_sub or newsletter_unsub depending on which button was pressed.
# in the context of a django.forms form
def clean(self):
if 'newsletter_sub' in self.data:
# do subscribe
elif 'newsletter_unsub' in self.data:
# do unsubscribe
You can also do like this,
<form method='POST'>
{{form1.as_p}}
<button type="submit" name="btnform1">Save Changes</button>
</form>
<form method='POST'>
{{form2.as_p}}
<button type="submit" name="btnform2">Save Changes</button>
</form>
CODE
if request.method=='POST' and 'btnform1' in request.POST:
do something...
if request.method=='POST' and 'btnform2' in request.POST:
do something...
one url to the same view!
like so!
urls.py
url(r'^$', views.landing.as_view(), name = 'landing'),
views.py
class landing(View):
template_name = '/home.html'
form_class1 = forms.pynamehere1
form_class2 = forms.pynamehere2
def get(self, request):
form1 = self.form_class1(None)
form2 = self.form_class2(None)
return render(request, self.template_name, { 'register':form1, 'login':form2,})
def post(self, request):
if request.method=='POST' and 'htmlsubmitbutton1' in request.POST:
## do what ever you want to do for first function ####
if request.method=='POST' and 'htmlsubmitbutton2' in request.POST:
## do what ever you want to do for second function ####
## return def post###
return render(request, self.template_name, {'form':form,})
/home.html
<!-- #### form 1 #### -->
<form action="" method="POST" >
{% csrf_token %}
{{ register.as_p }}
<button type="submit" name="htmlsubmitbutton1">Login</button>
</form>
<!--#### form 2 #### -->
<form action="" method="POST" >
{% csrf_token %}
{{ login.as_p }}
<button type="submit" name="htmlsubmitbutton2">Login</button>
</form>
It's an old question now, nevertheless I had the same issue and found a solution that works for me: I wrote MultiRedirectMixin.
from django.http import HttpResponseRedirect
class MultiRedirectMixin(object):
"""
A mixin that supports submit-specific success redirection.
Either specify one success_url, or provide dict with names of
submit actions given in template as keys
Example:
In template:
<input type="submit" name="create_new" value="Create"/>
<input type="submit" name="delete" value="Delete"/>
View:
MyMultiSubmitView(MultiRedirectMixin, forms.FormView):
success_urls = {"create_new": reverse_lazy('create'),
"delete": reverse_lazy('delete')}
"""
success_urls = {}
def form_valid(self, form):
""" Form is valid: Pick the url and redirect.
"""
for name in self.success_urls:
if name in form.data:
self.success_url = self.success_urls[name]
break
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
"""
Returns the supplied success URL.
"""
if self.success_url:
# Forcing possible reverse_lazy evaluation
url = force_text(self.success_url)
else:
raise ImproperlyConfigured(
_("No URL to redirect to. Provide a success_url."))
return url
I know this is old, but some of the answers are, to say the least, brief, and they do not address a common case where the form is not a django form.
This solution was inspired by this blog post. It relies on using a view class that is derived from django.views.generic.edit.FormMixin, e.g. CreateView, UpdateView or DeleteView. These provide the get_success_url method which exposes the button name in request
html
<html>
<body>
<form method="post">
<div>
<label> <input type="radio" name="select-type" value="A">Type A</label>
</div>
<div>
<label> <input type="radio" name="select-type" value="B">Type B</label>
</div>
<div>
<input type="submit" value="Use selected">
</div>
<div>
<input type="submit" name="no-selection" value="None of the above">
</div>
</form>
</body>
</html>
views.py
from django.views.generic import UpdateView
class GetType(UpdateView):
def get(self, request):
return render(request, 'get_type.html', {})
def post(self, request):
button = self.get_success_url()
print(button)
def get_success_url(self):
if 'no-selection' in self.request.POST:
return 'none selected'
return ''