I have a problem with opening a text file in django that is stored in my database. I want to access it via FileField of my model... the model looks something like this
class MyModel(models.Model):
saved_file = FileField()
I upload a test file via admin interface, which works ok. In my view I want to access this file. If I open it with standard python open() it works ok...
f = open(path, 'r')
a = f.readlines()
return render_to_response('base.html', {'content': a}, context_instance=RequestContext(request))
this displays lines of the file ok...
according to https://docs.djangoproject.com/en/dev/ref/models/fields/#filefield one gets a FieldFile proxy when FileField from a model is called, so
f = MyModel.objects.all().get(id=0).saved_file
should store FieldFile in f, furthermore documentation states that one opens a file from model by casting .open(mode='rb') on FieldFile, so
file = f.open(mode='rb')
should work like python .open() as stated in the documentation. So to get lines I do
file.readlines()
should return me list of lines. What happens is that I get an error saying that .readlines() atribute does not exist. I do not need the file to display it, this is just a way to test if opening a file works, but I need the file content in a variable in my view to further use it in my business logic.
Could anyone suggest a way to get the file content out of a FileField frem a model?
The documentation states that files are opened in 'rb' mode by default, but you would want to open in 'r' to treat the file as a text file:
my_object = MyModel.objects.get(pk=1)
try:
my_object.saved_file.open('r')
lines = my_object.saved_file.readlines()
finally:
my_object.saved_file.close()
Even better, you can use a context manager in Django v2.0+
my_object = MyModel.objects.get(pk=1)
with my_object.saved_file.open('r') as f:
lines = f.readlines()
Since Django 2.0 File.open does return you a file, so suggested way to work is as with context manager:
saved_file = MyModel.objects.all().get(id=0).saved_file
with saved_file.open() as f:
data = f.readlines()
Applies to old versions of Django < 2
FieldFile.open opens the file, but doesn't return anything. So in your example file is None.
You should call readlines on FieldFile. In your example it would be:
f = MyModel.objects.all().get(id=0).saved_file
try:
f.open(mode='rb')
lines = f.readlines()
finally:
f.close()
UPD: I added try/finally block, as the good practice is to always close the resource, even if exception happened.
Related
i have proplem here with my code
i am using for loop to save results in txt file
every time i use it it's saving the last line and delete the old line
here is code:
for i in domains:
requests.get(i)
if req.status_code == 200:
print('[+]:', i + '/')
file = open(save,'w')
file.write(domain)
file.close()
so after run the code it's save the last domain or last results and delete the old results
so i want solution
thanks.
Open the file in append mode:
open(filename,'a')
Your code should be:
for i in domains:
requests.get(i)
if req.status_code == 200:
print('[+]:', i + '/')
file = open(save,'a')
file.write(i)
file.close()
Try open it with a instead of w, so:
file = open(save, 'a')
it should appends to the file instead of writing to it
You sould use 'a' instead of 'w' in "file = open(save,'w')"
The problem here is arising because you are opening the file for writing on every iteration of the loop. Because you are opening the file with mode 'w', the file is being overwritten every time. (See documentation.)
It would be better to open the file once only, outside the loop.
For example:
file = open(save, 'w')
for i in domains:
# do some stuff...
file.write(some_data)
file.close()
You can also use with in conjuction with the open function:
with open(save, 'w') as file:
for i in domains:
# do some stuff...
file.write(some_data)
In this case, there is no need for an explicit call to file.close(). This will be done automatically when the loop ends, or even if something happens inside the with block like an exception being raised (i.e. error occurring) or a return from the function (if applicable).
Be aware that because of output buffering, data written to the file during one iteration might not actually get written to the file until some later iteration or after the file is closed. If this would be a problem, then you can insert a flush call to force a low-level write so that other processes can see the data:
with open(save, 'w') as file:
for i in domains:
# do some stuff...
file.write(some_data)
file.flush()
If there is some reason why you need to open the file inside the loop, then you could open it in append mode using 'a', and the data will be written after the end of the existing file. (Again, see the documentation linked earlier.) For example:
for i in domains:
# do some stuff...
file = open(save, 'a')
file.write(some_data)
file.close()
or again, better like this:
for i in domains:
with open(save, 'a') as file:
# do some stuff...
file.write(some_data)
Be aware that if the output file already exists before the program is started, then the contents of the existing file will remain because you are always opening it in append mode. Depending on your application, this might or might not be desirable.
I'm creating a file in my Web2Py code as follows:
tmpPckUpFile = open('FileContent.txt', 'w+')
I add to it
tmpPckUpFile.write("some stuff")
I close the file
tmpPckUpFile.close()
then try to update a row in the DB
db(db.project_pickup_approvals.id==request.args(0)).update(PickupContent = tmpPckUpFile)
At this point, I generally get an error:
I/O operation on closed file
so what I've tried doing is removing the close() and now the file gets added to the DB but nothing is written. I get a blank file.
Q: How can I write to the file and place it into the DB?
If you do not want to retain the original "FileContent.txt" temporary file on the filesystem, you can instead write the content to a StringIO object, which is a file-like object that does not require the creation of an actual file on the filesystem.
import cStringIO
tmpPckUpFile = cStringIO.StringIO()
tmpPckUpFile.write('some stuff')
tmpPckUpFile.seek(0)
upload_field = db.project_pickup_approvals.PickupContent
db(db.project_pickup_approvals.id == request.args(0)).update(
PickupContent=upload_field.store(tmpPckUpFile, filename='myfile.txt'))
tmpPckUpFile.close()
The above code should also work if you replace the first two lines with your original tmpPckUpFile = open('FileContent.txt', 'w+') line.
I'm using O365 for Python.
Sending an email and building the body my using the setBodyHTML() function. However at the present I need to write the actual HTML code inside the function. I don't want to do that. I want to just have python look at an HTML file I saved somewhere and send an email using that file as the body. Is that possible? Or am I confined to copy/pasting my HTML into that function? I'm using office365 for business. Thanks.
In other words instead of this: msg.setBodyHTML("<h3>Hello</h3>") I want to be able to do this: msg.setBodyHTML("C:\somemsg.html")
I guess you can assign the file content to a variable first, i.e.:
file = open('C:/somemsg.html', 'r')
content = file.read()
file.close()
msg.setBodyHTML(content)
You can do this via a simple reading of that file into a string, which you then can pass to the setBodyHTML function.
Here's a quick function example that will do the trick:
def load_html_from_file(path):
contents = ""
with open(path, 'r') as f:
contents = f.read()
return contents
Later, you can do something along the lines of
msg.setBodyHTML(load_html_from_file("C:\somemsg.html"))
or
html_contents = load_html_from_file("C:\somemsg.html")
msg.setBodyHTML(html_contents)
I am working on a project where I have to upload a file from file storage (via web form) to MongoDB. In order to achieve this, I need to open the file in "rb" mode, then encode the file and finally upload to MongoDb. I am stuck when opening the file "rb" mode.
if form.validate():
for inFile in request.files.getlist("file"):
connection = pymongo.MongoClient()
db = connection.test
uploads = db.uploads
with open(inFile, "rb") as fin:
f = fin.read()
encoded = Binary(f,0)
try:
uploads.insert({"binFile": encoded})
check = True
except Exception as e:
self.errorList.append("Document upload is unsuccessful"+e)
check = False
The above code is throwing TypeError: coercing to Unicode: need string or buffer, FileStorage found in the open step, i.e. this line:
with open(inFile, "rb") as fin:
Is there a way I can change my code to make it work?
Thanks in advance
The FileStorage object is already file-like so you can use as a file. You don't need to use open on it, just call inFile.read().
If this doesn't work for you for some reason, you can save the file to disk first using inFile.save() and open it from there.
Reference: http://werkzeug.pocoo.org/docs/0.11/datastructures/#werkzeug.datastructures.FileStorage
I am working on python and biopython right now. I have a file upload form and whatever file is uploaded suppose(abc.fasta) then i want to pass same name in execute (abc.fasta) function parameter and display function parameter (abc.aln). Right now i am changing file name manually, but i want to have it automatically.
Workflow goes like this.
----If submit is not true then display only header and form part
--- if submit is true then call execute() and get file name from form input
--- Then displaying result file name is same as executed file name but only change in extension
My raw code is here -- http://pastebin.com/FPUgZSSe
Any suggestions, changes and algorithm is appreciated
Thanks
You need to read the uploaded file out of the cgi.FieldStorage() and save it onto the server. Ususally a temp directory (/tmp on Linux) is used for this. You should remove these files after processing or on some schedule to clean up the drive.
def main():
import cgi
import cgitb; cgitb.enable()
f1 = cgi.FieldStorage()
if "dfile" in f1:
fileitem = f1["dfile"]
pathtoTmpFile = os.path.join("path/to/temp/directory", fileitem.filename)
fout = file(pathtoTmpFile, 'wb')
while 1:
chunk = fileitem.file.read(100000)
if not chunk: break
fout.write (chunk)
fout.close()
execute(pathtoTmpFile)
os.remove(pathtoTmpFile)
else:
header()
form()
This modified the execute to take the path to the newly saved file.
cline = ClustalwCommandline("clustalw", infile=pathToFile)
For the result file, you could also stream it back so the user gets a "Save as..." dialog. That might be a little more usable than displaying it in HTML.