I have a form like this:
<form action="{% url "forum.posts" forum=forum.slug thread=thread.slug %}" method="POST">
{% csrf_token %}
<div class="form-group">
<textarea class="form-control" placeholder="Začni tipkati.."></textarea>
</div>
<input type="submit" class="btn btn-success" value="Pošlji odgovor">
</form>
views.py
'''
Display all posts in a thread or create a new post in a thread.
'''
def posts(request, forum, thread):
forum = Forum.objects.get(slug=forum)
thread = Thread.objects.get(slug=thread)
if request.method == "POST":
return HttpResponse('ok')
posts = thread.posts.all()
return render(request, 'forum/posts.html', {
'forum': forum,
'thread': thread,
'posts': posts
})
urls.py (relevant part):
# List all posts in a thread / Submit a post to a forum
url(r'^(?P<forum>[-\w]+)/(?P<thread>[-\w]+)/$', 'forum.views.posts', name='forum.posts'),
HTML output:
<form action="/forum/o-spletiscu/novatemaa/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="4PQWDsAfHyjrhUnYU5P9vVhtaY3vLPBU">
<div class="form-group">
<textarea name="post-body" class="form-control" placeholder="Začni tipkati.."></textarea>
</div>
<input type="submit" class="btn btn-success" value="Pošlji odgovor">
</form>
After I hit submit, I expect ok to be returned, instead page refreshes and nothing happens.
Normal GET requests are working though..
What am I missing?
Edit:
It's working when I use #csrf_exempt on posts method.
page refreshes and nothing happens
Problem with your action value. try to inspect it and find wither the url is correct or not.
OR
your form does not have any input with name property.
Try this:
<form action="{% url "forum.posts" forum=forum.slug thread=thread.slug %}" method="POST">
{% csrf_token %}
<div class="form-group">
<textarea class="form-control" placeholder="Začni tipkati.." name="something"></textarea>
</div>
<input type="submit" class="btn btn-success" value="Pošlji odgovor">
</form>
Related
Here below my HTML-template
<form action="{% url 'test-data' %}" method="POST" name="test" enctype="multipart/form-data">
{% csrf_token %}
<h2>
{{ result }}
</h2>
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-primary">Show</button>
</div>
</form>
my View.py
def show_result(request):
if request.method == "POST":
result = request.POST.get('test')
return HttpResponse(result)
By pressing the button 'Show' I got None instead of {{ result }} value.
So, how I can get a Value inside curly brackets?
Thanks a lot for any help.
In order to submit the data, they need to be values of form elements like input, textarea, select options...
You can choose the right type for the input field. You can make use of the hidden field type to submit data that will not be displayed to the client...
You probably do not need to use the heading inside the form.
<h2>{{ result }}</h2>
<form action="{% url 'test-data' %}" method="POST" name="test" enctype="multipart/form-data">
{% csrf_token %}
<div class="d-flex justify-content-center">
<input type="hidden" name="result_field" value="{{ result }}" />
<button type="submit" class="btn btn-primary">Show</button>
</div>
</form>
On the backend, you can retrieve the data as follow:
result = request.POST.get('result_field')
I hope that works for you.
I have custom forms in the page suprated across the page
here is my first form
<form name="profile_image" class="edit-phto" method="POST" enctype="multipart/form-data">
<i class="fa fa-camera-retro"></i>
<label class="fileContainer">
Edit Display Photo
<input name="profile_image" value="" type="file" />
</label>
</form>
for profile picture
and i have another form for cover picture
<form name="cover_image" class="edit-phto" enctype="multipart/form-data">
<i class="fa fa-camera-retro"></i>
<label class="fileContainer">
Edit Cover Photo
<input name="cover_image" type="file" />
</label>
</form>
and another form for data :)
<form method="post" id="infoform" enctype="multipart/form-data">
{% csrf_token %}
.
.
.
.
<div class="submit-btns">
<button type="button" class="mtr-btn"><span>Cancel</span></button>
<button type="submit" class="mtr-btn" name="update"><span> Update</span></button>
</div>
and i have a form for search
<div class="searched">
<form method="post" class="form-search">
<input type="text" placeholder="Search Friend">
<button data-ripple><i class="ti-search"></i></button>
</form>
</div>
i just want to submit the 2 images forms and info forms when i click update button
is there a way to do sachthing in django without using form.as_p and stuff like that
Yes you can, you can just pass request.POST to each of your forms in the view and process each one as normal. However, you should be aware of conflicting names - the best way of managing this is to use form prefixes so that Django knows which bit of data relates to which form:
https://docs.djangoproject.com/en/4.0/ref/forms/api/#prefixes-for-forms
I have two forms on a page. The first form properly sends a POST request to my view but the second form sends a GET (I need it to also send a POST). I've made this mistake before and this time I made sure that the button is set to "submit", but for some reason it still sends a GET.
form 1 (working as intended):
<form method="POST">
{% csrf_token %}
<div class="row form-row">
<div class="col-sm-6">
<div class="form-group">
<label for="start_date">Start</label>
<input class="form-control" type="text" data-flatpickr data-alt-input="true" data-date-format="Y-m-d" name="start_date" data-enable-time="true">
</div>
<div class="form-group">
<label for="end_date">End</label>
<input class="form-control" type="text" data-flatpickr data-alt-input="true" data-date-format="Y-m-d" name="end_date" data-enable-time="true">
</div>
</div>
</div>
<input type="hidden" name="eventtype" value="availability">
<button class="btn btn-primary" type="submit">Save changes</button>
</form>
form 2 (sends a GET but I want this to POST):
<form method="POST">
{% csrf_token %}
{% if form.errors %}{{form.errors}}{% endif %}
<input type="hidden" name="pk" value="{{ i.id }}">
<input type="hidden" name="eventtype" value="invite">
<button class="btn btn-primary" type="submit">Confirm</button>
</form>
views.py
def createevent(request):
if request.method == 'GET':
<<code>>
else:
try:
eventtype = request.POST.get('eventtype', None)
print(eventtype)
if eventtype == "availability":
form = EventForm(request.POST)
newEvent = form.save(commit=False)
newEvent.mentor_user = request.user
newEvent.requester_user = None
newEvent.notes = None
newEvent.save()
elif eventtype == "invite":
form = EventForm(request.POST)
updatedEvent = form.save(commit=False)
updatedEvent.isConfirmed = True
updatedEvent.save()
return redirect('createevent')
except ValueError:
print(form.errors)
return render(request, 'events/createevent.html', {'form':EventForm(), 'error':'There was an error. Please make sure you entered everything correctly!'})
urls.py
# Events
path('events/create', views.createevent, name='createevent'),
# path('calendar/<slug:slug>', views.viewevent, name='viewevent'),
path('events/<int:pk>/edit', views.updateevent, name='updateevent'),
console output for form 1 and form 2:
"GET /events/create?csrfmiddlewaretoken=<<redacted>>&pk=2&eventtype=invite HTTP/1.1" 200 25560
"POST /events/create?csrfmiddlewaretoken=<<redacted>>&pk=2&eventtype=invite HTTP/1.1" 302 0
Set the action of form to your url path.
Look at this:
<form name="form" method="POST" action="{% url 'your_url_name' %}">
The issue ended up being the form was wrapped in another form tag further up in the template code. When I clicked the Submit button, the Submit button was firing on the first form and not the second. Just a bad copy/paste.
What I m trying to do:
Upload a CSV file(Form #1) and show header of a CSV file in the dropdown (Form #2).
and these forms are on the same page.
What I have tried:
for now I able to upload CSV file and display header in a webpage.
index.html
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="file1">Upload Files</label>
<div class="custom-file">
<input type="file" accept=".csv" id="file1" name="file" required="True" class="form-control custom-file-input">
<label class="custom-file-label" for="file1"></label>
</div>
</div>
<div class="form-group d-flex justify-content-center">
<button type="submit" class="btn text-white w-50" value="Upload">Upload</button>
</div>
</form>
views.py
def read_csv(request):
csv_file = request.FILES['file']
data = pd.read_csv(csv_file)
i = list(data.head(0))
context = {'loaded_data': i}
return render(request, "WebApp/index.html", context)
You can use AJAX request to handle this. You can check this answer, which has a sample AJAX request. In the views.py file, you can handle the request by checking request.is_ajax() and return the context you produce from CSV file via JsonResponse. At the success part of the AJAX call, you can manipulate the dropdown DOM element. There is a good tutorial here. If you are not familiar with these, feel free to ask about the parts you are confused.
So data was in a list I just have to loop through <option>:
<select class="custom-select" id="inputGroupSelect01">
{% for x in loaded_data %}
<option value="{{ x }}">
{{ x }}
</option>
{% endfor %}
</select>
I have a read-only textbox which preloaded value from database which upon a button click sends it's value to a method present in backend to perform DELETE query of sql. The problem is occuring when I am click on the button the method is invoked but the request.method condition is not invoked. It is directly going to the end return statement of the method.
#app.route('/home/delete_reminder/<string:id_val>',methods=['GET','POST'])
#is_logged_in
def delete_reminder(id_val):
if request.method=='POST':
desc = request.form['description']
x = desc.split(',')
cur = mysql.connection.cursor()
cur.execute('DELETE FROM set_reminder WHERE DATE=%s,SUBJECT=%s,DESCRIPTION=%s',[x[0],x[1],x[2]])
cur.execute('DELETE FROM recur WHERE RECUR_NEXT=%s',[id_val])
flash('Reminder Deleted','danger')
mysql.connection.commit()
cur.close()
return redirect(url_for('search_reminder_to_delete'))
This is my backend code.
<form method="POST">
{% for data in value %}
<div class="form-group">
<label>Description</label>
<input type="text" name="description" class="form-control" readonly="true" value="{{data.DATE}},{{data.SUBJECT}},{{data.DESCRIPTION}}">
</div>
Delete Reminder
{% endfor %}
</form>
This is the html part.
Your button isn't a button, it's a link. You aren't submitting your form.
If you want to fo that then you need to make you form tag:
<form method="POST" action="/home/delete_reminder/{{data.RECUR_NEXT}}">
and switch your button to be a real button that submits the form:
<div class="button">
<button type="submit" class="btn btn-warning">Send your message</button>
</div>
EDIT: Seeing that you want to have multiple possible routes for your form based on the loop.
You could try and use the formaction attribute, although it isn't going to be supported by every browser version.
<form method="POST">
{% for data in value %}
<div class="form-group">
<label>Description</label>
<input type="text" name="description" class="form-control" readonly="true" value="{{data.DATE}},{{data.SUBJECT}},{{data.DESCRIPTION}}">
</div>
<div class="button">
<button formaction="/home/delete_reminder/{{data.RECUR_NEXT}}" class="btn btn-warning" type="submit" class="btn btn-warning">Delete Reminder</button>
</div>
{% endfor %}
However this will still result in your description field that is passed to the request having every single description from the whole form in a list or possibly just the last one as a single value (I can't quite remember the behaviour of multiple inputs with the same name), which I don't think is what you're expecting to happen.
It may just be easiest to create a separate form for each link in a loop to be honest:
{% for data in value %}
<form method="POST" action="/home/delete_reminder/{{data.RECUR_NEXT}}">
<div class="form-group">
<label>Description</label>
<input type="text" name="description" class="form-control" readonly="true" value="{{data.DATE}},{{data.SUBJECT}},{{data.DESCRIPTION}}">
</div>
<div class="button">
<button class="btn btn-warning" type="submit" class="btn btn-warning">Delete Reminder</button>
</div>
</form>
{% endfor %}