Upload an image to twitter via tweepy from django form - python

I want to upload an image to twitter taken by a django form:
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
<form action="" method="POST" role="form" enctype="multipart/form-data">
{% csrf_token %}
<legend>Upload a file: </legend>
<div class="form-group">
<input type="file" name="file" class="form-control" id="">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
The image I got is:
if fileForm.is_valid():
print "file is uploaded."
paramFile = open(request.FILES['file'],'rb')
# paramFile = request.FILES['file'].read()
api.update_with_media(paramFile,status="Hello first image")
The error I got is:
coercing to Unicode: need string or buffer, InMemoryUploadedFile found
How can I upload this to twitter?

Method update_with_media() has only one positional argument which takes filename.
So you can specify filename something like this:
api.update_with_media(request.FILES['file'].name,
status="Hello first image")
Also you should pass file using keyword argument 'file':
api.update_with_media(request.FILES['file'].name,
file=request.FILES['file'],
status="Hello first image")

As per docs, you have to pass both file parameter which will be opened internally and filename parameter which is needed to determine MIME type and will be used to as form field in post data. So just pass them explicitly as keyword arguments and you should be fine.

Related

Django how to update a template without refreshing/redirecting?

I'm trying to make a simple commenting system where someone can add their comment to a post and it'll show up without having to redirect them or refresh the page. This is what my code basically looks like:
def post_details(request):
details = {}
if request.method == "POST":
request.POST
# Function here for creating a new comment
details['new_comment'] = new_comment
details['post_details'] = post_details
else:
details['post_details'] = post
return render(request, 'post_details.html', details)
The post_details.html shows a post with comments below it along with a form that adds their comment. I tried to add a new block of code in the template file for new_comment and the issue is that when I add a new comment, it will update that part but adding another one won't show up.
I should also note that I have CSV files that store the post and comment details. In my models.py file, I have my classes and methods to read in the CSV files so the function I left out does update the file with the comments. I'm trying to do this without Javascript but I'm open to trying anything, just really want to solidify my understanding of requests. I hope this wasn't confusing.
You can use JavaScript (AJAX) in this situation.
Create a base division in your template for showing your comments.
Then create an input form field for user to write comment.
Give the submit button id such as "addcomment" in my case.
Create the below ajax function with proper input values.
AJAX Function in JAVASCRIPT
$('#addcomment').click(function(){
// Taking_username_from_input_field_with_id_username.
var user = $('#username').val();
var usercomment = $('#usercomment').val(); // Taking_comment_from input_field_with_id_usercomment.
var csr = "{{csrf_token}}"; // Creating CSRF Token
$.ajax({
url: "{% url 'savecomment' blog.blog_id %}",
method:"POST",
data:{
user:user,
usercomment:usercomment,
csrfmiddlewaretoken:csr
},
success:function(data){
form.reset(); // resetting form values.
var output = "";
output =` <div class="comment">
<div class="comment-header d-flex justify-content-between">
<div class="user d-flex align-items-center">
<div class="image"><i class="fa fa-arrow-right"></i></div>
<div class="title"><strong>${data.user}</strong><span class="date">${data.date}</span></div>
</div>
</div>
<div class="comment-body">
<p>${data.comment}</p>
</div>
</div>`
$('.post-comments').append(output); // Appending data_in existing values which loaded_in first run.
//for_updating commentcount
var commentcount = data.number_of_comments;
$('.no-of-comments').replaceWith(`<span class="no-of-comments">(${commentcount})</span>`);
}
});
COMMENTS TEMPLATE
<div class="post-comments">
<header>
<h3 class="h6">Post Comments<span class="no-of-comments">0</span></h3>
</header>
</div>
FORM TEMPLATE
<form id="form" action="#" class="commenting-form">
<div class="row">
<div class="form-group col-md-6">
<input type="text" name="username" value="{{page.username}}" id="username" placeholder="Name"
class="form-control" disabled>
</div>
<div class="form-group col-md-12">
<textarea name="usercomment" id="usercomment" placeholder="Type your comment"
class="form-control"></textarea>
</div>
<div class="form-group col-md-12">
<button id="addcomment" type="button" class="btn btn-secondary">Submit Comment</button>
</div>
</div>
</form>

Get Data from Bootstrap Modal via POST request

I need to get data from a bootstrap modal input. I'am using the following code :
#app.route('/rejets_modeles', methods=("POST","GET"))
def rejets_modeles():
{code}
if request.method == 'POST':
uname = request.form['uname']
print("----")
print(uname)
return render_template ('rejets_modeles.html', tables=[df.to_html(table_id = 'rejets_modeles')], titles=df.columns.values, header="true")
And here is my HTML code
<form action="POST">
<div class="modal-body-modifs">
<p>Gestion du rejet : </p>
<label><b>NOM</b></label>
<input type="text" name="uname"></br>
<label><b>PRENOM</b></label>
<input type="text" name="uprenom"></br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-default" data-dismiss="modal"> OK</button>
</div>
</form>
I don't even have the ("---") printed, that means that my 'POST' request isnt' interpreted. How can I fix that ? Thank you
It has to be method instead of action
<form method="POST">
In action you can set url to which it has to send form data - ie.
<form method="POST" action="/rejets_modeles">
but if you want to send to the same url then you don't have to set it.
Solved. The problem was data-dismiss="modal" in my input tag. If you delete this the modal will close and the form will be sent via POST request.

Upload file in flask with other form elements fails with 400 error

Getting a 400, when trying to upload a file ad send other form elements to flask from html. Tried to use ajax, but that throws me an error as well.
Python:
#app.route('/prod_diff_result', methods=['POST', 'GET'])
def prod_diff_result():
try:
host = request.form['host-prod-iterator']
print(host)
if request.files['file']:
f = request.files['file']
f.save(secure_filename(f.filename))
HTML:
<div class="main-div">
<form action="/prod_diff_result" method="POST" enctype="multipart/form-data">
<div class="grid-container">
<div class="grid-item">
<span class="label label-default ">PROD</span><br>
<p>Iterator Host : <input type="text" class="form-control" id="host-prod-iterator" value="10.47.7.57"
required></p>
<input type="radio" name="data_fetch_type" value="file" onclick="showfile()">Upload File
<input type="file" name="file" />
<input type="radio" name="data_fetch_type" value="db"> Get from DB
<input type="submit" />
</div>
</form>
</div>
I want to be able send hostname and file back to flask error in one request and using one form.
It gives an error because you try to access a form field that it cannot find, and assumes that somehow the request was bad, because it didn't include a required form field. You are trying to access:
host = request.form['host-prod-iterator']
However you have simply not given it a name in your HTML. If you give it a name, it should work:
<p>Iterator Host :
<input type="text" class="form-control" name="host-prod-iterator" id="host-prod-iterator" value="10.47.7.57" required>
</p>

Python/Django pass user input as keyword arguments?

I am trying to pass what ever the user inputs into the url as keyword arguments (even if its not a real entry). When I try to assign the input name as the keyword arguments it fails.
HTML:
<p class="search">
<form method="GET" action="{% url 'job' %}" class="sidebar-form">
<div class="ogsearchbar input-group">
<input class="searchbarz" type="text" name="user_input" id="user_input" placeholder="Enter Job Number" autocomplete="off" />
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i></button>
</span>
</div>
</form>
</p>
Django:
def get_job(request):
if request.method == 'GET':
formvar = request.GET['user_input']
return HttpResponseRedirect('/jobs/' + formvar)
What you want doesn't make sense. The {{ }} signs denote a context variable which is passed into the template from the server, before the template is rendered. But you're trying to use a value which is only defined when the user actually types something into the rendered page itself.
You could probably do this with some Javascript, but there doesn't seem to be much point. Drop the parameter from the URL and let the form send it in the query params, which you can access in your view as request.GET.
I decided to just go with javascript since my django code was not working with a request method when refreshing the page.

uploading multiple files with pyramid

Trying to upload multiple files at once using python. The upload.html source code is as followed:
<form name="frmRegister" method="post" accept-charset="utf-8" enctype="multipart/form-data" class="form-horizontal">
<div class="control-group">
<div class="controls">
<input type="file" name="files" multiple='multiple'>
</div>
</div>
<div class="control-group">
<div class="controls">
<input class="btn btn-primary" type="submit" name="btnSubmit" value="Add Product" />
</div>
</div>
</form>
in my admin.py:
#view_config(context="mycart:resources.Product", name="add", renderer='admin/mall/product/add.jinja2', permission = 'admin')
#view_config(context="mycart:resources.Product", name="add", request_method="POST", renderer='admin/mall/product/add.jinja2', permission = 'admin')
def product_add(context, request):
if 'btnSubmit' in request.POST:
print ("files >>> ", request.POST['files'])
in my terminal, it is showing just FieldStorage('files', u'DSC01973.JPG') whereas I've selected 'DSC01975.JPG', 'DSC01976.JPG'.
Why is this so?
I've found a way to solve it, I believe there are many others, if there are, please feel free to holler out:
fileslist = request.POST.getall('files')
print ("My files listing: ", fileslist)
for f in fileslist:
print ( "individual files: ", f )
I could solve the problem with the following function:
from cgi import FieldStorage
def get_all_file_data_list(request):
return [x for x in request.POST.values() if isinstance(x, FieldStorage)]

Categories

Resources