Writing file line to Django model field - python

I can't seem to write a line from a file to a field of a Django model. The field is described in the model as:
text = models.TextField(null=True, blank=True, help_text='A status message.')
However, when I attempt to create a new object I cannot fill this field using the readline function:
file = open(filename, 'r')
str = file.readline()
When I attempt to use str for the text field I don't seem to be able to read or write to the database. I'm not given any error so I'm assuming its an encoding problem. Any advice? Thanks.
edit
The database is a postgres database and the field type is "text".
The code I'm using to create the object is:
Message.objects.create_message(sys, str)
and
def create_message(self, system, msg):
"""Create a message for the given system."""
m = Message.objects.create(system=system,
text=msg)
return m

Don't create variable names which conflict with python built in types. "str" is the string type.Python interpreter:
>> str
<type 'str'>

I think you're not calling the create_message method properly. Shouldn't you just call it like this
create_message(sys, str)
instead of this
Message.objects.create_message(sys, str)
?

Related

Attribute Error for Usage of Python Email Import

def ExtractBody(self, msg):
content = ""
if msg.is_multipart():
for payload in msg.get_payload():
content += str(payload.get_payload())
else:
content += str(msg.get_payload())
return content
Hello everyone, with the code above, I was trying to extract the body of a .eml file from a class, but when I used the code above, it gives me the error as shown below.
Why is this so, and how can I fix it?
For extra information, I am getting this email from a web server that makes use of flask.
<class 'AttributeError'>
'bytes' object has no attribute 'read'
EDIT: I have a temporary fix to the problem
I am not sure why, but when I shifted the method from the class to the .py file itself, the code now works.

AttributeError: 'file' object has no attribute '_committed'

I have a DjangoFileField in my model. I am trying to convert the type of the audio from that FielField to mp3 and then again trying to save it. But after converting the type and exporting it using pydub it is returning the following error
AttributeError: 'file' object has no attribute '_committed'
My code is like this
def get_from_function(AudioSegment, format):
form = "from_{0}".format(format)
print form
if hasattr(AudioSegment, form):
return getattr(AudioSegment, form)
return None
audio = request.FILES.get('audio', None)
if audio:
name_list = audio.name.rsplit(".")
voice_format =name_list[1]
from_format = get_from_function(AudioSegment, voice_format)
if from_format and callable(from_format):
sound = from_format(audio)
audio = sound.export("media/{0}".format(name_list[0]), mp3")
when i print the audio it prints
<open file 'media/barsandtone', mode 'wb+' at 0x7f771e5e2f60>
and when i print the type of file it prints
<type 'file'>
but when i assign the audio field to django model like
Mymodel.objects.create(audio=audio)
it gives error
AttributeError at /create/
'file' object has no attribute '_committed'
What is the correct way to save the exported file into django model
django needs a ContentFile usually to do this passing it a stream of data, and it doesn't work the way you usually pass arguments to a model. The proper way to do this is the following
from django.core.files.base import ContentFile
[...]
mymodel = Mymodel()
mymodel.audio.save(audio.name, ContentFile(audio.read()))
don't forget to pass the stream to ContentFile. Django won't raise any errors if you pass it ContentFile(audio) but in that case you won't save the file content..
I got same error that is solved now i would suggest you to open that file in read mode then save it. here is my code :
from django.core.files import File as DjangoFile
file_obj1 = DjangoFile(open(file_name, mode='rb'), name=file_name)
File.objects.create(title=file_name, file=file_obj1, content_object=task_obj, author=task_obj.client)
In my case I was creating a django form with some FileFields for which I wanted to show the currently existing file from a model's instance. I'm leaving this answer here in case anyone else end up here for similar reasons, even though I know that this answer doesn't apply to the OP's situation.
Normally you would bound the form and the model but in this case it's not possible for reasons a bit long to explain, so I wanted to query the model to obtain the File field and make it be the initial data.
It reached a point where I managed to make it work until the view can render the field and the currently existing field (as it's normally rendered by the ClearableFileInput widget).
That point was reached by filling self.fields["field_name"].initial with either:
Using a DummyFile class:
class DummyFile:
def __init__(self, url, name):
self.url = url
self.name = name
def __str__(self):
return self.name
Filling it with the existing instance, like
self.fields[field_name].initial = doc.file.instance
self.fields[field_name].initial.url = doc.file.url
But then in both cases the AttributeError: 'file' object has no attribute '_committed' was raised when uploading a file, although it was correctly uploaded and saved.
Solution
Turned out that it behaves different when you assign the initial data for a field by using self.fields[field_name].initial than using self.initial[field_name], and doing it like this worked like a charm:
doc = Document.objects.filter(
filters_to_locate_the_model_instance=this_and_that,
).first()
if doc:
self.initial[field_name] = doc.file
The HTML is rendered with the link to the existing file, it loads fine if there is not an existing file, and uploads and saves a file without any error.

Django database sqlite display of value of attribute

I'm on a project using django and I wrote my models.py
I have two classes
class Adresse(models.Model):
numV=models.IntegerField(blank=False,null=False)
complementdest=models.TextField(blank=False,null=False)
complementadr=models.TextField(blank=False,null=False)
commune=models.TextField(blank=False,null=False)
codeP=models.IntegerField(blank=False,null=False)
pays=models.TextField(blank=False,null=False)
def __str__(self):
return self.numV
return self.complementdest
return self.complementadr
return self.commune
return self.codeP
return self.pays
def __Adr__(self):
return self.adr1.all()
and
class CompteCandidat(myUser):
sexe = models.TextField(max_length=10)
datecr = models.DateTimeField(auto_now_add = True)
adresse=models.OneToOneField('Adresse',related_name='adr1',null=True, default=None)
def __str__(self):
return self.first_name
return self.last_name
return self.email
return self.sexe
def __Adr__(self):
return self.adresse.all()
I try to do some tests like this:
adresse=Adresse(numV='254',complementdest='xxxxx',complementadr='Eugene napoleon',commune='Paris',codeP='75012',pays='France')
c1=CompteCandidat(username='Luna',first_name='celia',last_name='durand',password='CCC',email='hello2#gmail.com',type='candidat',adresse=adresse)
adresse.save()
c1.save()
and when I try to see what I have in my Adresse or in my CompteCandidat by using this command it didn't work
>>> Adresse.__getattribute__(numV)
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'numV' is not defined
i want to know what i'm suppose to do to display what I have in Adresse and CompteCandidat in order to be sure that the add works
i know i Can do :
>>> adresse.numV
'254'
but it works only in the console there is an another way to consult all the database without using the name of the temporery variables ????
You can use
Adresse.objects.all()
to see all records or Adresse.object.filter(numV='254)
to see records satisfying this condition.
For full reference please check:
https://docs.djangoproject.com/ja/1.9/topics/db/queries/
At first in the console try this:
>>>A = {numV='254',complementdest='xxxxx',complementadr='Eugene napoleon',commune='Paris',codeP='75012',pays='France'}
>>> adresse = Adresse(**A)
>>> adresse.save()
At first you will face an error beacuse your numV is Integer but you are assigning an String to it, so should edit numV = '254' to numV = 254 at first line.
Then try above steps again and post that in which step face error.
Two things :
__str__ must only return a single string - as it stands your code tries to return multiple non string values.
the __getattribute__ method (and it's counterpart getattr) should be passed the name of the attribute i.e. a string. Also you shouldn't be trying to call __getattribute__ directly except in exceptional circumstances: ie. you have some form of circular access confilct - which you don't here.
There is no reason that adresse.numV shouldn't work directly in your code - that is the normal way to retrieve attributes from an instance. You should only use getattr if you have the attribute name in a string from elsewhere.
At the risk of sounding rude - if you are struggling to write code that correctly accesses attributes then maybe trying to write a Django App is a case of trying to run before you walk.

TypeError: cannot concatenate 'str' and 'SFType' objects (simple-salesforce)

my project is to extract the contents of all my salesforce tables, including the custom ones. To do this, I need to know the names of the columns (fields), since SOQL does not support "SELECT * from TABLENAME".
With simple-salesforce, I know that the following works:
sf = Salesforce(username='foo#bar.com', password='abcd', security_token='ZCdsdPdE4eI2DZMl5gwCFIGEFU')
field_data = sf.Contact.describe()["fields"]
But my problem is that I need to parameterize the "Contact" string in the actual method call above, so that I can call this method for objects that I do not know the names of (ie not defined in standard salesforce). For example I need to do:
field_data = sf.CustomTableName.describe()["fields"]
When I try and use the SFType class:
contact = SFType('Contact',sf.sessionid,sf.sf_instance)
f = contact.describe()
I get this error:
Traceback (most recent call last):
File "./simple-example.py", line 13, in <module>
f = contact.describe()["fields"]
File "/Library/Python/2.7/site-packages/simple_salesforce/api.py", line 430, in describe
result = self._call_salesforce('GET', self.base_url + 'describe')
File "/Library/Python/2.7/site-packages/simple_salesforce/api.py", line 570, in _call_salesforce
'Authorization': 'Bearer ' + self.session_id,
TypeError: cannot concatenate 'str' and 'SFType' objects
Thanks in advance for any advice.
If you look in the source code for simple-salesforce (as of 2015-11-12) you'll see that in the init() of Salesforce() we set the session to self.session_id and instance to self.sf_instance
In your case, you're using sf.sessionid, and because simple-salesforce is setup to return a SFType() object whenever a method or property does not exist on Salesforce() (and sessionid does not exist on Salesforce()) you're actually inserting a SFType() object into the init of your SFType()
SFType.__init__() doesn't do any form of validation to confirm you're passing in strings as arguments, so the error you're getting is from simple-salesforce trying to use the SFType() object you're passing in as a string.
Try this code:
contact = SFType('Contact', sf.session_id, sf.sf_instance)
f = contact.describe()
I ran into the same issue and seemed to have fixed this by removing the protocol ("https://") from the instance_url. This is weird but seems to work for me now and I can do contact.describe()
Something like this:
contact = SFType(sf_object, session_id, instance_url.replace("https://",''))
contact.describe()

AppEngine -> "AttributeError: 'unicode' object has no attribute 'has_key'" when using blobstore

There have been a number of other questions on AttributeErrors here, but I've read through them and am still not sure what's causing the type mismatch in my specific case.
Thanks in advance for any thoughts on this.
My model:
class Object(db.Model):
notes = db.StringProperty(multiline=False)
other_item = db.ReferenceProperty(Other)
time = db.DateTimeProperty(auto_now_add=True)
new_files = blobstore.BlobReferenceProperty(required=True)
email = db.EmailProperty()
is_purple = db.BooleanProperty()
My BlobstoreUploadHandler:
class FormUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
try:
note = self.request.get('notes')
email_addr = self.request.get('email')
o = self.request.get('other')
upload_file = self.get_uploads()[0]
# Save the object record
new_object = Object(notes=note,
other=o,
email=email_addr,
is_purple=False,
new_files=upload_file.key())
db.put(new_object)
# Redirect to let user know everything's peachy.
self.redirect('/upload_success.html')
except:
self.redirect('/upload_failure.html')
And every time I submit the form that uploads the file, it throws the following exception:
ERROR 2010-10-30 21:31:01,045 __init__.py:391] 'unicode' object has no attribute 'has_key'
Traceback (most recent call last):
File "/home/user/Public/dir/google_appengine/google/appengine/ext/webapp/__init__.py", line 513, in __call__
handler.post(*groups)
File "/home/user/Public/dir/myapp/myapp.py", line 187, in post
new_files=upload_file.key())
File "/home/user/Public/dir/google_appengine/google/appengine/ext/db/__init__.py", line 813, in __init__
prop.__set__(self, value)
File "/home/user/Public/dir/google_appengine/google/appengine/ext/db/__init__.py", line 3216, in __set__
value = self.validate(value)
File "/home/user/Public/dir/google_appengine/google/appengine/ext/db/__init__.py", line 3246, in validate
if value is not None and not value.has_key():
AttributeError: 'unicode' object has no attribute 'has_key'
What perplexes me most is that this code is nearly straight out of the documentation, and jives with other examples of blob upload handler's I've found online in tutorials as well.
I've run --clear-datastore to ensure that any changes I've made to the DB schema aren't causing problems, and have tried casting upload_file as all sorts of things to see if it would appease Python - any ideas on what I've screwed up?
Edit: I've found a workaround, but it's suboptimal.
Altering the UploadHandler to this instead resolves the issue:
...
# Save the object record
new_object = Object()
new_object.notes = note
new_object.other = o
new_object.email = email.addr
new_object.is_purple = False
new_object.new_files = upload_file.key()
db.put(new_object)
...
I made this switch after noticing that commenting out the files line threw the same issues for the other line, and so on. This isn't an optimal solution, though, as I can't enforce validation this way (in the model, if I set anything as required, I can't declare an empty entity like above without throwing an exception).
Any thoughts on why I can't declare the entity and populate it at the same time?
You're passing in o as the value of other_item (in your sample code, you call it other, but I presume that's a typo). o is a string fetched from the request, though, and the model definition specifies that it's a ReferenceProperty, so it should either be an instance of the Other class, or a db.Key object.
If o is supposed to be a stringified key, pass in db.Key(o) instead, to deserialize it.
Object is a really terrible name for a datastore class (or any class, really), by the way - the Python base object is called object, and that's only one capitalized letter away - very easy to mistake.
has_key error is due to the ReferenceProperty other_items. You are most likely passing in '' for other_items when appengine's api expects a dict. In order to get around this, you need to convert other_items to hash.
[caveat lector: I know zilch about "google_app_engine"]
The message indicates that it is expecting a dict (the only known object that has a has_key attribute) or a work-alike object, not the unicode object that you supplied. Perhaps you should be passing upload_file, not upload_file.key() ...

Categories