Skip to content

Commit 930566d

Browse files
committed
show case new feature file_name and fix #15 with an answer
1 parent 29282fe commit 930566d

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

doc/source/index.rst

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Please open the file `polls/views.py <https://github.com/chfw/django-excel/blob/
152152
form = UploadFileForm(request.POST, request.FILES)
153153
if form.is_valid():
154154
filehandle = request.FILES['file']
155-
return excel.make_response(filehandle.get_sheet(), "csv")
155+
return excel.make_response(filehandle.get_sheet(), "csv", file_name="download")
156156
else:
157157
form = UploadFileForm()
158158
return render_to_response('upload_form.html', {'form': form}, context_instance=RequestContext(request))
@@ -267,6 +267,8 @@ When a dictionary of key maps is supplied, its keys should be the field names in
267267

268268
The custom formatting function is needed when the data from the excel sheet needs translation before data import. For example, **Choice** has a foreign key to **Question**. When choice data are to be imported, "Question" column needs to be translated to a question instance. In our example, "Question" column in "Sheet 2" contains the values appeared in "Unique Identifier" column in "Sheet 1".
269269

270+
271+
270272
Handle data export
271273
++++++++++++++++++++++++++++++
272274

@@ -283,12 +285,66 @@ Now let's examine the code behind this in `polls/views.py <https://github.com/ch
283285

284286
def export_data(request, atype):
285287
if atype == "sheet":
286-
return excel.make_response_from_a_table(Question, 'xls')
288+
return excel.make_response_from_a_table(Question, 'xls', file_name="sheet")
287289
elif atype == "book":
288-
return excel.make_response_from_tables([Question, Choice], 'xls')
290+
return excel.make_response_from_tables([Question, Choice], 'xls', file_name="book")
289291
290292
:meth:`~django_excel.make_response_from_tables` does all what is needed: read out the data, convert them into xls and give it the browser. And what you need to do is to give a list of models to be exported and a file type. As you have noticed, you can visit http://localhost:8000/polls/export/sheet and will get **Question** exported as a single sheet file.
291293

294+
295+
How to import one sheet instead of multi-sheet book
296+
*****************************************************
297+
298+
Previous example shows how to import a multi-sheet book. However, what exactly is needed to import only one sheet instead? Before you proceed, please empty question and choice data using django admin.
299+
300+
Let's visit this url first http://localhost:8000/polls/imports_sheet/, where you see a similar file upload form. This time please choose `sample-sheet.xls <https://github.com/chfw/django-excel/blob/master/sample-sheet.xls>`_ instead. Then look at django admin and see if the question data have been imported or not.
301+
302+
Now let's look at the code::
303+
304+
def import_sheet(request):
305+
if request.method == "POST":
306+
form = UploadFileForm(request.POST,
307+
request.FILES)
308+
if form.is_valid():
309+
request.FILES['file'].save_to_database(
310+
name_columns_by_row=2,
311+
model=Question,
312+
mapdict=['question_text', 'pub_date', 'slug'])
313+
return HttpResponse("OK")
314+
else:
315+
return HttpResponseBadRequest()
316+
else:
317+
...
318+
319+
Becuase it is a single sheet, the function to call is :meth:`~django_excel.ExcelMixin.save_to_database` where you specify a model and its mapping dictionary.
320+
321+
Have you noticed the extra parameter 'name_columns_by_row'? Why is this needed? Well, normally you *will not need* that if you have column names in the first row. In this example, the column names appears in the second row. Please open `sample-sheet.xls <https://github.com/chfw/django-excel/blob/master/sample-sheet.xls>`_ and have a look. The straight answer is because the column names in the data appears in the 2nd row of the data matrix.
322+
323+
.. note::
324+
325+
If you have imported earlier excel sheet "sample-data.xls", you will get the following warning in your console output::
326+
327+
Warning: Bulk insertion got below exception. Trying to do it one by one slowly.
328+
column slug is not unique <- reason
329+
One row is ignored <- action
330+
column slug is not unique
331+
What is your favourite programming language?
332+
One row is ignored
333+
column slug is not unique
334+
What is your favourite IDE?
335+
336+
337+
This is because question data have been imported before. Django is raising IntegrityError. For more details please read `this part of code in pyexcel-io <https://github.com/pyexcel/pyexcel-io/blob/master/pyexcel_io/djangobook.py#L98>`_, and `django-excel issue 2 <https://github.com/pyexcel/django-excel/issues/2>`_
338+
339+
In order to remove those warnings, what you can do is to empty all data using django admin and redo this single sheet import again.
340+
341+
342+
What to do if import data overlaps existing data in the database
343+
******************************************************************
344+
345+
With new version pyexcel-io v0.1.0, you could provide the row initialization function that returns None in order to skip a row in your import data. Inside the initialization function, you could also do database update. As long as it returns None, django-excel will try to do bulk create the import data.
346+
347+
292348
Handle custom data export
293349
+++++++++++++++++++++++++++++++
294350

@@ -300,7 +356,7 @@ It is also quite common to download a portion of the data in a database table, f
300356
question = Question.objects.get(slug='ide')
301357
query_sets = Choice.objects.filter(question=question)
302358
column_names = ['choice_text', 'id', 'votes']
303-
return excel.make_response_from_query_sets(query_sets, column_names, 'xls')
359+
return excel.make_response_from_query_sets(query_sets, column_names, 'xls', file_name="custom")
304360

305361
You can visit http://localhost:8000/polls/export/custom and will get the query set exported as a single sheet file as:
306362

polls/views.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def upload(request):
2525
form = UploadFileForm(request.POST, request.FILES)
2626
if form.is_valid():
2727
filehandle = request.FILES['file']
28-
return excel.make_response(filehandle.get_sheet(), "csv")
28+
return excel.make_response(filehandle.get_sheet(), "csv", file_name="download")
2929
else:
3030
form = UploadFileForm()
3131
return render_to_response(
@@ -50,18 +50,20 @@ def download_as_attachment(request, file_type, file_name):
5050
def export_data(request, atype):
5151
if atype == "sheet":
5252
return excel.make_response_from_a_table(
53-
Question, 'xls')
53+
Question, 'xls', file_name="sheet")
5454
elif atype == "book":
5555
return excel.make_response_from_tables(
56-
[Question, Choice], 'xls')
56+
[Question, Choice], 'xls', file_name="book")
5757
elif atype == "custom":
5858
question = Question.objects.get(slug='ide')
5959
query_sets = Choice.objects.filter(question=question)
6060
column_names = ['choice_text', 'id', 'votes']
6161
return excel.make_response_from_query_sets(
6262
query_sets,
6363
column_names,
64-
'xls')
64+
'xls',
65+
file_name="custom"
66+
)
6567
else:
6668
return HttpResponseBadRequest("Bad request. please put one of these \
6769
in your url suffix: sheet, book or custom")

0 commit comments

Comments
 (0)