Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion binder/plugins/views/csvexport.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,12 @@ def get_datum(data, key, prefix=''):
else:
# Assume that we have a mapping now
fk_ids = data[head_key]
if type(fk_ids) != list:

if fk_ids is None:
# This case happens if we have a nullable foreign key that is null. Treat this as a many
# to one relation with no values.
fk_ids = []
elif type(fk_ids) != list:
fk_ids = [fk_ids]

# if head_key not in key_mapping:
Expand Down
30 changes: 27 additions & 3 deletions tests/plugins/test_csvexport.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.core.files import File
from django.contrib.auth.models import User

from ..testapp.models import Picture, Animal
from ..testapp.models import Picture, Animal, PictureBook
import csv
import openpyxl

Expand All @@ -31,8 +31,10 @@ def setUp(self):

self.pictures = []

picture_book = PictureBook.objects.create(name='Holiday 2012')

for i in range(3):
picture = Picture(animal=animal)
picture = Picture(animal=animal, picture_book=picture_book)
file = CsvExportTest.temp_imagefile(50, 50, 'jpeg')
picture.file.save('picture.jpg', File(file), save=False)
picture.original_file.save('picture_copy.jpg', File(file), save=False)
Expand All @@ -48,6 +50,7 @@ def setUp(self):

def test_csv_download(self):
response = self.client.get('/picture/download_csv/')
print(response.content)
self.assertEqual(200, response.status_code)
response_data = csv.reader(io.StringIO(response.content.decode("utf-8")))

Expand Down Expand Up @@ -123,4 +126,25 @@ def test_context_aware_download_xlsx(self):
self.assertEqual(list(_values[2]),
[self.pictures[1].id, str(self.pictures[1].animal_id), (self.pictures[1].id ** 2)])
self.assertEqual(list(_values[3]),
[self.pictures[2].id, str(self.pictures[2].animal_id), (self.pictures[2].id ** 2)])
[self.pictures[2].id, str(self.pictures[2].animal_id), (self.pictures[2].id ** 2)])

def test_none_foreign_key(self):
"""
If we have a relation that we have to include which is nullable, and we have a foreign key, we do not want the
csv export to crash. I.e. we also want for a picture to export the picture book name, even though not all pioctures
belong to a picture book
:return:
"""
self.pictures[0].picture_book = None
self.pictures[0].save()

response = self.client.get('/picture/download/')
self.assertEqual(200, response.status_code)
response_data = csv.reader(io.StringIO(response.content.decode("utf-8")))

data = list(response_data)
content = data[1:]

picture_books = [c[-1] for c in content]

self.assertEqual(['', 'Holiday 2012', 'Holiday 2012'], picture_books)
2 changes: 1 addition & 1 deletion tests/testapp/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .gate import Gate
from .nickname import Nickname, NullableNickname
from .lion import Lion
from .picture import Picture
from .picture import Picture, PictureBook
from .zoo import Zoo
from .zoo_employee import ZooEmployee
from .city import City, CityState, PermanentCity
Expand Down
13 changes: 13 additions & 0 deletions tests/testapp/models/picture.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ def delete_files(sender, instance=None, **kwargs):
except Exception:
pass


class PictureBook(BinderModel):
"""
Sometimes customers like to commemorate their visit to the zoo. Of course there are always some shitty pictures that
we do not want in a picture album

"""

name = models.TextField()



# At the website of the zoo there are some pictures of animals. This model links the picture to an animal.
#
# A picture has two files, the original uploaded file, and the modified file. This model is used for testing the
Expand All @@ -21,6 +33,7 @@ class Picture(BinderModel):
animal = models.ForeignKey('Animal', on_delete=models.CASCADE, related_name='picture')
file = models.ImageField(upload_to='floor-plans')
original_file = models.ImageField(upload_to='floor-plans')
picture_book = models.ForeignKey('PictureBook', on_delete=models.CASCADE, null=True, blank=True)

def __str__(self):
return 'picture %d: (Picture for animal %s)' % (self.pk or 0, self.animal.name)
Expand Down
2 changes: 1 addition & 1 deletion tests/testapp/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from .gate import GateView
from .lion import LionView
from .nickname import NicknameView
from .picture import PictureView
from .picture import PictureView, PictureBookView
from .user import UserView
from .zoo import ZooView
from .zoo_employee import ZooEmployeeView
7 changes: 5 additions & 2 deletions tests/testapp/views/picture.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
from binder.views import ModelView
from binder.plugins.views import ImageView, CsvExportView

from ..models import Picture
from ..models import Picture, PictureBook

class PictureBookView(ModelView):
model = PictureBook

class PictureView(ModelView, ImageView, CsvExportView):
model = Picture
file_fields = ['file', 'original_file']
csv_settings = CsvExportView.CsvExportSettings(['animal'], [
csv_settings = CsvExportView.CsvExportSettings(['animal', 'picture_book'], [
('id', 'picture identifier'),
('animal.id', 'animal identifier'),
('id', 'squared picture identifier', lambda id, row, mapping: id**2),
('picture_book.name', 'Picturebook name')
])

@list_route(name='download_csv', methods=['GET'])
Expand Down