Export data as csv is not working in django - django

I'm currently trying to export a csv file if the print button is clicked.
The problem is the file which generated is not .csv file
However, the file content is retrieve the values which I need (I checked by changing type of file manually. Hereby I attached the result).
Could anyone show me the mistakes? Or is it related to any requirement plugin?
Any and all help is greatly appreciated!
import csv
query_data = search_data(request,request.user.userid)
if (request.method == 'POST'):
if 'csvexport' in request.POST:
data = csv_export(query_data)
return HttpResponse (data,content_type='text/csv')
--
def csv_export (data):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="file.csv"'
writer = csv.writer(response)
response.write('\ufeff'.encode('utf8'))
writer.writerow([,'valData'
,'value1'
,'value2'])
for rec in data:
writer.writerow([rec['valData']
,rec['value1']
,rec['value2']])
return response
--
def search_data(request,userid):
cursor = connection.cursor()
query = str("SELECT\n"
" valData,\n"
" MG0.valData as value1,\n"
" MG1.valData as value2,\n"
" FROM\n"
" T_USER AS TU\n"
" LEFT JOIN M_GENERAL AS MG0\n"
" ON MG0.Cd='001'\n"
" LEFT JOIN M_GENERAL AS MG1\n"
" ON MG1.Cd='001'\n")
cursor.execute(query)
row = dictfetchall(cursor,)
return row

Try this,
if (request.method == 'POST'):
if 'csvexport' in request.POST:
return csv_export(query_data)

Related

Django : can't interrupt update function with redirect. Is it possible?

I use a function for updating a Model.
def update_mapping(request, pk):
flow = Flow.objects.get(pk=pk)
mappings = MappingField.objects.filter(fl_id=pk)
headers_samples = GetCsvHeadersAndSamples(request, pk)
[...]
In this function, I call another one (GetCsvHeadersAndSamples) for getting datas from a CSV. Later, I use those datas with JS in the template.
def GetCsvHeadersAndSamples(request, flow_id):
get_file_and_attribs = get_csv(request, flow_id)
file = get_file_and_attribs[0]
separator = get_file_and_attribs[1]
encoding = get_file_and_attribs[2]
with open(file, newline='') as f:
reader = csv.reader(f, delimiter=separator,
encoding=encoding)
headers = next(reader)
samples = next(itertools.islice(csv.reader(f), 1, None))
headersAndSamples = {'headers': headers, 'samples': samples}
return headersAndSamples
For accessing CSV datas, I use another function for checking if the CSV still exists, in which case, I retrieve datas in it.
def get_csv(request, flow_id):
flow = Flow.objects.get(pk=flow_id)
file = flow.fl_file_name
separator = flow.fl_separator
media_folder = settings.MEDIA_ROOT
file = os.path.join(media_folder, str(file))
if os.path.isfile(file):
file_2_test = urllib.request.urlopen('file://' + file).read()
encoding = (chardet.detect(file_2_test))['encoding']
return (file, separator, encoding)
else:
# print('No file')
messages.error(request, "File not found or corrupted.")
return HttpResponseRedirect(reverse('mappings-list', args=(flow_id,)))
I hoped that the return would "break" my original function and would redirect to the 'mappings-list' page with the message.error. But it continues and returns to GetCsvHeadersAndSamples function that generates an error because CSV datas were not found. Nota: the commented print however shows well that the file is not found.
It seems that the way I'm doing things is not the good one.

Read user uploaded csv file and store data in Django modele live on heroku

This is my firts question here. so I would like to thank you for your help.
I have a Django School management app. and i would like the user to be able to read csv file and store in database with specific header.
My code runs locally very well. but I recently push it on heroku so that I can test it. I may note that all static assets are stored on Amazon s3. and it works.
but when I try to read a csv file, I get an Internal server error.
here is my code to store Pupils.
def convert_header(csvHeader):
cols = [ x.replace(' ', '_').lower() for x in csvHeader ]
return cols
def import_data(request):
if request.method == 'GET':
return render(request, 'school/import.html')
if request.method == 'POST' and request.FILES['myfile']:
if request.POST.get("object") == '':
message = 'You may chose an object'
return render(request, 'school/import.html', {'message': message })
if request.POST.get("object") == 'Pupil':
myfile = request.FILES['myfile']
fs = FileSystemStorage(location='eSchool/media/documents')
filename = fs.save(myfile.name, myfile)
uploaded_file_url = fs.path(filename)
data = csv.reader(open(uploaded_file_url), delimiter=',')
header = next(data)
header_cols = convert_header(header)
i = 0
k = 0
for row in data:
pupil = Pupil()
for k in range(len(header_cols)):
row_item = row[k].split(',')
for item in row_item:
key = header_cols[k]
if key == 'responsible':
item = Responsible.objects.get(pk= int(item))
print(item.first_name)
setattr(pupil, key, item)
else:
setattr(pupil, key, item)
k +=1
pupil.save()
i = i + 1
detailed = 'Sucessfully created '+ str(i) + ' Pupils '
return render(request, 'school/import_success.html', {'detailed' : detailed })
I would like to store data in a modele called Document. I create it. and try it I still get the error. Please help.
I find the solution of that problem. I first create a Django model to store the url of the uploaded file. like that:
class Document(models.Model):
uploaded_at = models.DateTimeField(auto_now_add=True)
upload = models.FileField(upload_to='documents')
Obvously I had to configure MEDIA_ROOT and MEDIA_URL
I configure the settings file to store the reference of all media assets and all static file on Amazon s3.
So instead of using the class FileSystemStorage. I install with pip a package named "requests"
pip install requests
and I import requests,csv and codecs.
import requests
import codecs
After that my view I just make litle modification tm my function.
def import_data(request):
if request.method == 'GET':
return render(request, 'school/import.html')
if request.method == 'POST' and request.FILES['myfile']:
if request.POST.get("object") == '':
message = 'You may chose an object'
return render(request, 'school/import.html', {'message': message })
if request.POST.get("object") == 'Pupil':
myfile = request.FILES['myfile']
doc = Document()
doc.upload = myfile
doc.save()
print(doc.upload.url)
if settings.DEBUG == True: # execute that block locally
data = csv.reader(open(doc.upload.path), delimiter=',') # locally the file is red frm the path so i us doc.upload.path
else: #this block is executed in production. So the file is red from the url. so I use doc.upload.url
rep = requests.get(doc.upload.url)
text = codecs.iterdecode(rep.iter_lines(), 'latin_1') #codecs is use to decode the lines. I don't really master how it works.
data = csv.reader(text, delimiter = ',')
header = next(data)
header_cols = convert_header(header)
i = 0
k = 0
for row in data:
pupil = Pupil()
for k in range(len(header_cols)):
row_item = row[k].split(',')
for item in row_item:
key = header_cols[k]
if key == 'responsible':
item = Responsible.objects.get(pk= int(item))
#print(item.first_name)
setattr(pupil, key, item)
else:
setattr(pupil, key, item)
k +=1
pupil.save()
i = i + 1
detailed = 'Sucessfully created '+ str(i) + ' Pupils '
return render(request, 'school/import_success.html', {'detailed' : detailed })
So right now. everything work well. If you see something that i can improve about this code, I Already thank you for your help!

Postgres vs SQL lite page not found discrapancy

I have my dev environment with django - SQLlite and my prod is with django
- Postgres
I have view that works perfectly on SQL lite
login_required
def receipt_pdf(request,pk):
try:
Receipt_payment_id_dict = Receipt_payment.objects.filter(is_active = True ).aggregate(Max('id'))
if Receipt_payment_id_dict:
Receipt_payment_id = Receipt_payment_id_dict['id__max']
Receipt_payment_dict = get_object_or_404(Receipt_payment, pk=Receipt_payment_id)
else:
Receipt_payment_dict = "no data"
except ValueError:
raise Http404("At least one active value should be in -Receipt_payment-, contact your administrator")
try:
general_id_dict = General_configurations.objects.filter(is_active = True ).aggregate(Max('id'))
if general_id_dict:
general_id = general_id_dict['id__max']
general_dict = get_object_or_404(General_configurations, pk=general_id)
else:
general_dict = "no data"
except ValueError:
raise Http404("At least one active value should be in -General_configurations-, contact your administrator")
payment = get_object_or_404(LeasePayment, pk=pk)
# leasetenant = lease.tenant_set.all().order_by('-id')
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="Receipt.pdf"'
buffer = BytesIO()
# Create the PDF object, using the BytesIO object as its "file."
p = canvas.Canvas(buffer)
But When I execute same code with Postgres I get
No Receipt_payment matches the given query.
What could be the problem?

Django : python pandas generating blank excel

I am using pandas tool to create downloadable excel file.Excel will get it data from SQL table , which in turn will get populated depending on values entered by user.I have attached one download button in my web page to download the excel.
On clicking download button it's generating a blank excel file with sheet name and file name as Consistency Report. Can anyone point out what I am doing wrong here.
Thanks in advance
views.py
def export_excel(request):
response = HttpResponse(content_type="application/vnd.ms-excel")
response['Content-Disposition'] = 'attachment; filename=Consistency Report.xls'
fname = 'Consistency Report.xls'
cnxn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};SERVER=******;DATABASE=testing;UID=***;PWD=******')
cursor = cnxn.cursor()
cursor.execute("select * from dhm_consis_report_tbl")
columns = [column[0] for column in cursor.description]
data=cursor.fetchall()
cursor.commit()
print(columns)
for i in range(0,len(data)):
data[i]=tuple(data[i])
df = ps.DataFrame(data=data,columns=columns)
writer = ps.ExcelWriter('Consistency Report.xls',engine='xlwt')
df.to_excel(writer,sheet_name='Report')
writer.save()
return response
So, I edited my views.py and am able to generate and download excel file but the problem is that the file is now downloading at two locations; one at my project folder and one at my download folder.Also the file at download folder is empty while the one at my project folder contains data.Can anybody explain why this is happening?
Modified views.py
def export_excel(request):
response = HttpResponse(content_type="application/vnd.ms-excel;charset=utf-8")
response['Content-Disposition'] = 'attachment; filename=Consistency Report.xls'
df = ps.DataFrame.from_records(DHM_Consis_Report.objects.values('conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id'))
print(df)
writer = ps.ExcelWriter('Consistency Report.xls',encoding='utf-8')
df.to_excel(writer,sheet_name='Report')
writer.save()
return response
Finally, I was able to generate required excel.Earlier I was creating and writing the excel with data but my HttpResponse was not getting the required data.I put the logic regarding generating excel in separate function and logic regarding downloading the generated file in separate function.This is what I did.
I know it's crude and inefficient but this works for me.If anyone has better way to do this please share.
views.py
#login_required
def consisreports(request):
cust= customername
username=None
if request.user.is_authenticated():
username=request.user.username
print(username)
table=ConsisReport(DHM_Consis_Report.objects.all())
RequestConfig(request,paginate={"per_page": 25}).configure(table)
todays=date.today()
todays=todays.strftime("%d-%m-%y")
filename="Consistency Report %s as on %s %s.xls"%(cust,str(todays),username)
colname=['Customer','Query ','Count','Desc','Criticality','Status','Rundate','Instance ID']
df = ps.DataFrame.from_records(DHM_Consis_Report.objects.values('conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id'))
df=df[['conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id']]
print(df)
#df.save('C:/Users/P1097/Desktop')
writer = ps.ExcelWriter(filename)
df.to_excel(writer,sheet_name='Report',index=False,engine='xlsxwriter',header=colname)
writer.save()
return render(request, 'consistency/consresult.html', {'table': table,'customername':cust})
#login_required
def export_excel(request):
custname=customername
username=None
if request.user.is_authenticated():
username=request.user.username
todays=date.today()
todays=todays.strftime("%d-%m-%y")
filename="Consistency Report %s as on %s %s.xls"%(custname,str(todays),username)
wrapper=open(filename,"rb")
cont=wrapper.read()
response = HttpResponse(cont,content_type="application/vnd.ms-excel;charset=utf-8")
response['Content-Length']=os.path.getsize(filename)
size=os.path.getsize(filename)
print(size)
wrapper.close()
response['Content-Disposition'] = 'attachment; filename= %s'%filename
return response

Django optimize query update

I have a function which opens a txt file (350k lines), reads each line and updates fields in the database. The database has around 250k-300k records.
It runs way too slow for me.
Could you help me with optimizing it the query or the way the import is being done?
Query:
PlaceGroupMatch.objects.filter(**query_kwargs).update(sym_ul=int(line[5]), updated=True, updated_date=datetime.now())
Whole code:
def street_postal_codes():
output_file_name = os.path.join(settings.MEDIA_ROOT, "postal", "ulice_GUS.txt")
with open(output_file_name, 'r+') as handle:
next(handle)
lines = csv.reader(handle, delimiter='\t')
lines = list(lines)
def update_data(lines):
transaction.set_autocommit(False)
for index, line in enumerate(lines):
query_kwargs = {
"sym_ext": int(line[10]),
"sym_pod":int(line[4]),
"updated": False
}
qs = PlaceGroupMatch.objects.filter(**query_kwargs).update(sym_ul=int(line[5]), updated=True, updated_date=datetime.now())
print index
if index % 5000 == 0:
print index, datetime.now()
transaction.commit()
transaction.set_autocommit(True)
update_data(lines)