Django Form post action - django

So I can't figure it out how to make form submit action link to external website be invisible in inspect element. For example I got my html form something like this:
<form method='POST' action='some link to external website'> <div>{{ form }}</div>
Is it possible to make it hidden or not ?

You shouldn't do this, the browser has to know where to send requests. Although, this answer may help you.

Related

django redirect after post with post parameters after update

I was looking for help but couldn't find any suitable solution.
I would like to ask about redirect after POST.
Situation looks as below step by step:
Simple search form with POST with parameter called 'find' within form. Search form appears on every site and if i call search on site with devices i'm checking referrer and i'm doing query for device model fields and results go to devices.html template. Same situation is when I search within localization site, checking for referrer and querying for model fields of localization model and returning query result in localization.html template.
When I try to update device i'm opening new edit device template with url '/edit/device/dev_id' when every field of this model is shown so i can update some fields manually.
After commiting changes on edit site device 'post' goes to url 'update/device/dev_id' and changes to device are saved properly.
The problem is how can I redirect after updating device to step number one where are the results of search view for devices?
If i redirect after update ('update/device/dev_id') device to 'request.META.get('HTTP_REFERER')' i'm getting 'edit/device/dev_id' url ?
Worth to mention is that method POST for search form sends text search input to action="/search" and then after checking referrer shows results, so there is nothing like 'action="search/find".
I know that in web browser we can do few times previous click to show search results incuding POST parameters but it is not the point.
If you have any ideas how to redirect to search results (method POST, 1 point) after updating please let me know.
Regards AD
I will try to simplify the question ( too much code to paste ):
Given search below in template:
<form class="navbar-form navbar-left" action="/search" method="post">{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" name="find" placeholder="Search">
</div>
<button type="submit" class="btn btn-default" >Search</button>
</form>
in views.py:
def search_dev(request):
to_find=request.POST.get('find')
(..)
<--query updating_fields in instance considering only 1 search result-->
redirect ? (to search query with POST )
Is it possible to go back to search results after some changes to instance ( for example update ) considering only 1 search result ?

How to implement django-allauth in homepage as modal?

There are few questions based on this idea like:
Implementing Ajax requests / response with django-allauth
Log in / Sign up directly on home page
https://www.reddit.com/r/django/comments/30lz11/django_allauth_implement_loginsignup_on_homepage/
but I need a little more help. I understand that I have to make form action url of modal as {% url 'account_login' %}. I have included {% load account %} and changed the 'name' and 'id' of username and password fields. My question is what other things I need to do to achieve this as it is still not working.
I had the same question and I wrote little tutorial for 3 methods I found so far. You can find details at https://stackoverflow.com/a/39235634/4992248
P.S. If it was just one method, I would post it here, but because I do not know which one you would prefer, I simply give you a link.

Submit Button Confusion and Request being sent Twice (Using Flask)

I'm pretty much trying to create a web app that takes 2 svn urls and does something with them.
The code for my form is simple, I'm also using WTForms
class SVN_Path(Form):
svn_url=StringField('SVN_Path',[validators.URL()])
I'm trying to create 2 forms with 2 submit buttons that submit the 2 urls individually so my test3.html looks like this:
<form action="" method="post" name="SVNPath1">
{{form1.hidden_tag()}}
<p>
SVN Directory:
{{form1.svn_url(size=50)}}
<input type="submit" value="Update">
<br>
{% for error in form1.svn_url.errors %}
<span style="color: red;">[{{error}}]</span>
{% endfor %}
</p>
</form>
<form action="" method="post" name="SVNPath2">
{{form2.hidden_tag()}}
<p>
SVN Directory:
{{form2.svn_url(size=50)}}
<input type="submit" value="Update">
<br>
{% for error in form2.svn_url.errors %}
<span style="color: red;">[{{error}}]</span>
{% endfor %}
</p>
</form>
MY FIRST QUESTION is how do I know which submit button was clicked so I can run the proper function on the corresponding svn url. I have tried doing something like
if request.form1['submit'] == 'Update':
if request.form2['submit'] == 'Update':
but that does not work at all. I'm new to web dev in general and flask so a detailed explanation would be helpful.
SECONDLY, since submits weren't working properly I also tried an alternative to keep my work moving so in my .py file I have
#app.route('/test3', methods=['GET','POST'])
def test3():
basepath=createDir()
form1=SVN_Path()
form2=SVN_Path()
if request.method=="POST":
if form1.validate_on_submit():
svn_url = form1.svn_url.data
prev_pdf=PDF_List(svn_url,basepath,'prev') #some function
if form2.validate_on_submit():
svn_url2 = form2.svn_url.data
new_pdf=PDF_List(svn_url,basepath,'new') #some function
return render_template('test3.html', form1=form1, form2=form2)
CreateDir is a function that creates a directory in the local /tmp using timestamps of the local time.
Whenever I go the webpage it creates a directory, lets call it dir1, since its calling CreateDir. Thats what I want, but when I click submit on the form it creates another directory dir2 in the tmp folder which is NOT what I want since I want everything to being the same dir1 directory.
In addition when I put a url in one of the forms and click submit, it automatically puts it the same value in the 2nd form as well.
Sorry if this is really long and possibly confusing, but any help is appreciated.
:) Let's see if we can clarify this a little.
To your first question:
As #dim suggested in his comment, You have a few options:
You can submit your form to separate unique urls. That way you know which form was submitted
You can create two similar but different Form classes (the fields will need different names like prev_svn_url and cur_svn_url). This way in your view function, you instantiate two different forms and you'll know which form was submitted based on form.validate_on_submit()
The third option would be to add a name attribute to your submit button and then change the value attributes to something like 'Update Previous' and 'Update Current'. This way in your view function you can check the value of request.data[<submit button name>] to determine if 'Update Previous' was pressed or 'Update Current'.
To your second question:
Multiple directories are being created because you're calling createDir() each time the page is loaded to show the forms and when the forms get posted. In order to create just once, you'll need some kind of logic to determine that the directory was not previously created before calling createDir()
In addition: Since both forms are from the same SVN_Path class, they read post data exactly the same way, that's why whatever you type in form 1 appears in form 2.
Now for my 2 cents:
I assume you're trying to write some kind of application that takes two SVN urls as input, creates a folder and does something with those URLs in that folder. If this is the case, the way you are currently going about it is inefficient and won't work well. You can achieve this with just one form class having 2 svn_url fields (with different names of course) and then handling all of that in one post.
EDIT: The job of the submit button is to tell the browser that you're ready to send the data on the form to the server. In this case you should only need one submit button (SubmitFiled => when rendered). Clicking that one submit button will send data from both input fields to your view function.
Your form should look something like:
class SVN_Path(Form):
prev_svn_url=StringField('Previous SVN_Path',[validators.URL()])
new_svn_url=StringField('New SVN_Path',[validators.URL()])
and your view function:
def test():
form = SVN_Path()
if request.method == "POST":
if form.validate_on_submit():
basepath = createDir() # Only create dir when everything validates
prev_svn_url = form.prev_svn_url.data
new_svn_url = form.new_svn_url.data
prev_pdf = PDF_List(prev_svn_url, basepath, 'prev')
new_pdf = PDF_List(new_svn_url, basepath, 'new')
...
return render_template('test3.html', form1=form1, form2=form2)

Using Bootstrap wysiwyg text editor in Django Form

I am using Django and Bootrap 2.32. I want to include this wysiwyg-bootrap-themed text editor: http://mindmup.github.io/bootstrap-wysiwyg/. The usage of this editor is fairly simple, including
$('#editor').wysiwyg();
in the JS-declaration will render each
<div class=editor></div>
into a beatiful wysiwyg text-editor.
Now the problem: I want to include this editor into one of my django form field. I have the single form:
class Article_Form(ModelForm):
Article_text = CharField(widget=Textarea(attrs = {'id' : 'editor'}))
class Meta:
model= Article
, whereas the Article model includes one simple CharField . Is there any chance, to get the editor work inside the Article_text form-field? With the above-mentioned widget, the created textarea cannot be controlled by the wysiwyg-editor-control buttons. Wrapping the form-template-tag like this
<div id="editor">
{{ Article_Form.Article_text }}
</div>
doesn't work either. The problem thus is that Django creates a textarea, wheras the editor would need a <div> to render correctly. Do you guys have any idea how to get this to work (without refering to django-wysiwyg).
Thanks!
I don't know enough about Django but I wrote the editor you're referring to, so here's a suggestion. Assuming the other answer on this page is correct and you can't generate a div directly, you can generate a text area using whatever Django templates you would normally do, then assign two events:
1) page onload event that would copy the textarea contents into the div, something like
$('#editor').html($('#textarea').val())
2) form onsubmit event that would reverse copy the current div contents into the textarea before it gets submitted
$('#textarea').val($('#editor').html())
Take a look at this.
Summernote is a simple WYSIWYG editor based on Twitter's Bootstrap.
django-summernote plugin allows you to embed Summernote into your Django admin page very handy.
https://github.com/lqez/django-summernote
Are you sure that this "plugin" doesn't work with textarea?
{{ Article_Form.Article_text }}
will be rendered to something like:
<textarea cols="40" id="id_Article_text" name="Article_text" rows="10"></textarea>
So there is a chance that you can initialize the wysiwyg editor like:
$('#id_Article_text').wysiwyg();
However after checking the plugin, I doubt that would be possible since it is using contenteditable="true" attribute of HTML5 and probably the plugin works with div only.
So there is no way you can make it work natively with Django form. The solution should be display other fields of your form manually, hide the one with textarea and display the editor instead:
<form action="" method="POST">
{{ Article_Form.field1 }}
{{ Article_Form.field2 }}
<div class=editor></div>
{% csrf_token %}
<input type="submit" value="Submit" id="submit-btn" />
</form>
Then you can use JS to submit your form:
$('#submit-btn').click(function (e) {
e.preventDefault();
$.ajax({
// do your magic here.
// note that you can get the content of the editor with: $('#editor').cleanHtml();
})
});
This way is hackish I agree so I don't recommend you go for it, just find other plugin then. Also please read PEP 8 carefully.
Hope it helps.
Take a look at this repo: https://github.com/rochapps/django-secure-input
I think it solves most of your problems.

Render to response to a redirected url in Django

In a form submission scenario, form is post to "/submit". I want to redirect user to "/sucess" on success and pass render some message to a template at new url. How to do this in Django? render_to_response doesn't do redirect and HttpResponseRedirect doesn't do template rendering.
The response from Daniel Roseman is potentially dangerous, opening your site to XSS vulnerabilities.
Make sure you strip html tags from whatever message is passed if you must do it this way.
A better way would be to redirect to /success/?msg=ok, and have in your view a dictionary:
{ 'ok': 'Your success message' }
If your success page needs a dynamic message, you need to pass it there somehow. You can either do this via GET parameters in the URL you are redirecting to - eg return HttpResponseRedirect('/success/?msg=My+success+message+here') - or by setting some values in the session, which the success view can pick up.
The best way to do what you want is:
In your view set the success message (or error message) as a dict. And use the render_to_response to display any template.
In your template you can verify if there is a message and if the message is an error message or a success message.
Some like this:
In your view:
if anyError:
dict = {"message" : {"error" : "The error message"}}
else:
dict = {"message" : {"success" :"The success message"}}
in your template:
{% if message %}
{% if message.error %}
{{ message.error }}
{% else %}
{{ message.success }}
{% endif %}
{% endif %}
Hope i've helped
There is no good way to do what you want. The browser submits the form, which will take the user to /submit. Once you decide whether it's "successful", it's too late; the browser has already decided on it's destination. All you can do is redirect. But, as you're finding out, it's going to be hard to keep your POST state when you redirect.
I would give up on this. It's not how websites are supposed to work.
I think Django does this already if you extend the generic view. On create there's an optional argument "post_save_redirect". This functionality is used in the automatically generated Django admin system. For example if you want a new resource, say user, you go to the url "/user/add". After you submit it redirects you to "/user/1" with a success message "you just saved user #1". So this is possible, but I'm still researching how to do it without extending the generic view. I'm still very new to Django and python, so looking through Django core to find how they did it is not so easy for me.
I would recommend to use Django message framework which is used for one-time notification messages.
https://docs.djangoproject.com/en/1.8/ref/contrib/messages/