MultiValueDictKeyError when Djano Imagefield is blank - django-models

I have a very simple model and form which expects user to fill in name , title etc. and also upload an image . Everything works fine but as soon as user tries to submit a record without uploading the image then it gets Multivaluedictkey error. I have set null =true and blank = true in the field definition. :"photo = models.ImageField(upload_to='media',null=True,blank=True)" . Media storage and retrieval is also working fine as long as image is uploaded by the user.In short I request your help in suggesting snything which enables me to let user submit a record without necessarily uploading an image.
Traceback:
File "/home/sampledemo/.virtualenvs/django18/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/sampledemo/mysite/polls/views.py" in someview
45. newproject.photo = request.FILES['photo']
File "/home/sampledemo/.virtualenvs/django18/local/lib/python2.7/site-packages/django/utils/datastructures.py" in __getitem__
322. raise MultiValueDictKeyError(repr(key))
Exception Type: MultiValueDictKeyError at /someview/
Exception Value: "'photo

In your code you have
newproject.photo = request.FILES['photo']
you will get MultiValueDictKeyError for the following reasons
1. request.FILES does not have the key named photo
2. request.FILES may have multiple values for the same key
If it's the 2nd case you should use request.FILES.getlist('photo') [if you upload multiple files with the same. In your case it's 'photo']

Related

Sending attachments as an email from a form - NOT from local files

I have created a HTML email form which allows a user to enter To, subject, message, content and attachments however I cannot get the attachments to send.
I have researched online and came across many variations of this code:
messageBodyPart = new MimeBodyPart();
String filename = "/home/manisha/file.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
But is there a way of sending attachments input into the form instead of adding the file path to a file in the code?
Thanks
First, the files need to be uploaded from the browser to the server using the html form. Depending on what you're using to manage the uploaded data, you can store the file data in memory or in files on the server. If you store it in memory, you can use a ByteArrayDataSource instead of FileDataSource in your code above.

Getting more data from messages.get in C#

I'm having trouble getting more than just the snippet for text data for the message I am trying to retrieve using the Gmail API. Here is the piece of test code I am working with:
public string GetMail()
{
GmailService service = (GmailService)HttpContext.Current.Session["service"];
Message messageFeed = service.Users.Messages.List("me").Execute().Messages.First();
UsersResource.MessagesResource.GetRequest getReq = new UsersResource.MessagesResource.GetRequest(service, "me", messageFeed.Id);
getReq.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Full;
Message message = getReq.Execute();
return message.Raw;
}
For some reason, when I call message.Raw, it is returning null. I am able to retrieve other properties as what the format=minimal setting would based off of the API playground example I was playing with.
However in my code, I am setting the format enum to "full", yet I am still unable to retrieve the full data of the message.
Am I completely missing something here?
Seems like you're mixing up formats and response types. If you want the raw message as a string in Message.raw then you need to set:
getReq.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Raw;
If you want the parsed message back (in the "payload" field) then you can use getReq.Format of Full like you have.
Acceptable values are:
"full": Returns the parsed email message content in the payload field and the raw field is not used. (default)
"minimal": Only returns email message metadata such as identifiers and labels, it does not return the email headers, body, or payload.
"raw": Returns the entire email message content in the raw field as a string and the payload field is not used. This includes the identifiers, labels, metadata, MIME structure, and small body parts (typically less than 2KB).
from: https://developers.google.com/gmail/api/v1/reference/users/messages/get

How to get the attached file of a received mail using python and store it in a blob property field

I am trying to get the attached file from the received mail and store it as Blob property in the GAE datastore. I am using Google app engine Python.
The file should be added to datastore only if the file is a excel file. Following code shows the method i have used for this. In that class 'mail_message.attachments' will give a list of attachments of the received mail. From that we can get only the file name and file content . But here i have to get the format of the file for checking whether it's a excel file. so that's why i have used the following method.
class LogSenderHandler(InboundMailHandler):
def receive(self, mail_message):
file_format_supported=['application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet','application/vnd.ms-excel']
for payload_no in range(len(mail_message.original.get_payload())):
one_payload = mail_message.original.get_payload(payload_no)
if one_payload.get_content_type() in file_format_supported:
uploadfile=Files()
uploadfile.temp_file=one_payload
uploadfile.put()
this code gives me the error
Property temp_file must be convertible to a Blob instance (Blob() argument should be str instance, not instance)
what i want to do converting the payload type as "str instance" to store it as blob property.
**Is there any other method to find the file type after getting the attachment list using mail_message.attachments. File content got from this attachment list can be stored to GAE datastore as blob property after decoding **.

GAE/J - Blobstore - how to determine if file is not uploaded

I am working on web application and using GAE/J blobstore tutorial http://code.google.com/appengine/docs/java/blobstore/overview.html I was able to upload file to blobstore.
My Problem is my "upload file" option is OPTIONAL on form. So user may or maynot choose to upload the file on my form. So since this field is optional, I do not have any upfront form validation for this field, but then when i submit the form "a blank document with 0kb file gets uploaded to blobstore" since i am not able to determine if user has selected any file or not inside servlet.
I tried Apache file upload (ServletFileUpload..etc) but it keeps returning null everytime.
so not sure, how do i determine if user have selected any file to upload inside servlet?
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
if (blobs != null && blobs.size() > 0) {
BlobKey blobkey = blobs.get("myFile");
blobkeyStr = blobkey.getKeyString();
}
You can test if a blob was uploaded by checking the size of the blob. If the size is zero, you should delete the blob.
BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService();
BlobKey blobKey = bs.getUploads(req).get("blob").get(0);
final BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(blobKey);
long size = blobInfo.getSize();
if(size > 0){
//process blob
}else{
bs.delete(blobKey);
}
In the dev environment if the user submits a form with an empty file upload, the blobkey will be null, but in production it will be non-null and the blob will be empty. So you should check for both scenarios.
FYI it may be more helpful for you to show your code.
Basically, even though your file upload is optional, you still need to send the request from the form submission through the blobstore upload url anyway. If a file was uploaded, your upload handler that gets control from GAE will be able to get a list (map) of all blobs. If no file was uploaded, that list will be empty. From there, you can process the rest of the form submission as you choose.
For the specifics of how to get that list of uploaded blobs, see this section of the documentation, but basically you're going to make this call:
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
If that map is empty, there were no blobs uploaded.
I'm assuming that you are using a form to submit directly to your upload URL? If so, you might want to add validation code on your form itself. If they've selected the form then do an async request to get an upload url to submit to. If there is no form attached then submit to a different URL that doesn't process the blob.
So for instance, when they submit, if the form is attached, submit to your servlet that generates the upload URL like this:
BlobstoreService service = BlobstoreServiceFactory
.getBlobstoreService();
String url = service
.createUploadUrl("/uploadurl");
return url;

How can i extract attachments from salesforce?

I need to extract attatchments out of salesforce? I need to transfer some notes and attachments into another environmant. I am able to extract the notes but not sure how to go about extracting the attatchments
Thanks
Prady
This mostly depends on what tools/utilities you use to extract. The SOQL for Attachment sObject will always return one row at a time if Body field is included in the query. This is enforced to conserver resources and prevent overbearing SOQL scripts.
Approach #1, if queryMore is not available: Issue a SOQL without Body field to enumerate all attachments, then issue one SOQL per attachment ID to retrieve Body
Approach #2: Issue a SOQL to retrieve all needed attachments then loop using queryMore to get them one at a time.
Approach #3: If you can "freeze" the SF environment and just want to take snapshot of the system to pre-load a different one to be used going forward you can use "data exports". In setup menu, in data management there is an export data command, make sure you click "Include in export" to include all binary data. After due process it will give you a complete data backup you can crunch offline.
Btw, body is base64 encoded, you'll need to decode it to get the actual binary
Here is the solution I've used to get the attachment binary content from SalesForce. The example in their documentation points the following:
curl
https://na1.salesforce.com/services/data/v20.0/sobjects/Document/015D0000000NdJOIA0/body
-H "Authorization: Bearer token"
So there are a couple different elements here. The host (https://na1.salesforce.com) you should be able to get after the login process, this host is session based so it can always change. Second element is the rest of the URL, that you will get from the "body" field of the Attachment object. Third and last element is the Authorization header, which is composed by the string "Bearer ", plus the token that is given to you after you authenticate with the SF backend.
The response is the binary file, it is NOT in base64, just save it to a file and you are good to go.
Here is an example of how I did it in Objective C:
// How to get the correct host, since that is configured after the login.
NSURL * host = [[[[SFRestAPI sharedInstance] coordinator] credentials] instanceUrl];
// The field Body contains the partial URL to get the file content
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", [host absoluteString], {AttachmentObject}.body]];
// Creating the Authorization header. Important to add the "Bearer " before the token
NSString *authHeader = [NSString stringWithFormat:#"Bearer %#",[[[[SFRestAPI sharedInstance] coordinator] credentials] accessToken]];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
[urlRequest addValue:authHeader forHTTPHeaderField:#"Authorization"];
[urlRequest setHTTPMethod:#"GET"];
urlConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
Hope it helps.
You can use SOQl Query options, or if you are looking for some automation tool that will help you with quick export, then you can try AppExchange App Satrang Mass File Download - https://appexchange.salesforce.com/listingDetail?listingId=a0N3A00000EcsAOUAZ&tab=e
Disclaimer: I work at Satrang Technologies, the publisher of this Mass File Download AppExchange App.
In SalesForce attachment will be against an Object for e.g. Account object.
Steps to retrieve attachment (in Java)
Get the ID of the Object to which a file is attached. e.q. Account Object
String pid = Account__r().getId();
Execute a Query on Salesforce Object "Attachment" for the ID in Step 1
*String q = "Select Name, Body, ContentType from Attachment
where ParentId = '" + pid + "'";
QueryResult qr = connection.query(q);
SObject[] sarr = qr.getRecords();*
SObject so = sarr[0];
Typecast Salesforce Generic Object (SObject) to "Attachment" object
*Attachment att = (Attachment)so;*
Retrieve the Byte Array Stream from Body of Attachment, and do the operation needed on byte array.
*byte[] bName = att.getBody();
// Do your operation in byte array stream*

Resources