I am trying to upload files to Pipedrive, our CRM, when a lead is being submitted. Everything below here works according to plan, except my views.py when it calls the lead_file_upload() function. I get the following error:
expected str, bytes or os.PathLike object, not S3Boto3StorageFile
I am assuming this is a result of me using AWS S3 Storage and the file_data = default_storage.open(file.file.file, 'rb') on an S3Boto3StorageFile object. How do I open an S3Boto3StorageFile object which can then be passed on to the lead_file_upload() function?
models.py:
class Lead(models.Model):
lead_name = models.CharField(max_length=50)
timestamp = models.DateTimeField(auto_now_add=True)
comments = models.TextField(blank=True)
submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL)
def __str__(self):
return self.lead_name
class LeadFile(models.Model):
file = models.FileField(upload_to="lead/%Y/%m/%d", blank=True)
lead = models.ForeignKey(Lead, on_delete=models.CASCADE)
forms.py:
from django import forms
from django.forms import ClearableFileInput
from .models import LeadFile
class LeadForm(forms.Form):
coop_name = forms.CharField(max_length=50,
label = "Name of lead")
comments = forms.CharField(max_length=2000, widget=forms.Textarea({}), required=False)
class LeadFileModelForm(forms.ModelForm):
class Meta:
model = LeadFile
fields = ['file']
widgets = {
'file': ClearableFileInput(attrs={'multiple': True}),
}
labels = {
'file': 'Add files',
}
views.py:
def lead(request):
title = 'Submit lead'
user = request.user
if request.method == 'POST':
form = LeadForm(request.POST)
fileform = LeadFileModelForm(request.POST, request.FILES)
files = request.FILES.getlist('file')
if form.is_valid() and fileform.is_valid():
lead_name = form.cleaned_data['lead_name']
comments = form.cleaned_data['comments']
lead = Lead(lead_name=lead_name, comments=comments, submitted_by=user)
lead.save()
for f in files:
file = LeadFile(file=f, offer=lead)
file.save()
file_data = default_storage.open(file.file.file, 'rb')
lead_file_upload(file_data, offer)
file_data.close()
# Ship things to Pipedrive
ship_note_to_pipedrive = lead_upload(lead)
else:
form = LeadForm()
fileform = LeadFileModelForm()
context = {'title': title, 'form': form, 'fileform': fileform}
return render(request, 'lead.html', context)
The lead_file_upload() function:
def lead_file_upload(the_file, instance):
headers = {'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded'}
files = {'file': the_file}
data = {'deal_id': str(instance.lead_name)}
pd_token = os.getenv("PIPEDRIVE_TOKEN")
url = 'https://api.pipedrive.com/v1/files?api_token=%s' %pd_token
r = requests.post(url, files=files, data=data, headers=headers)
return r.status_code