Wagail: Read & parse the contents of an uploaded file
In Wagtail I wanted a clean way to upload a file (like CSV or JSON) to the admin, parse it, and make it available to the front-end. This is handy for small chunks of data that you don't want to have to build a model for, or edit/update field-by-field each time the data changes. Instead, editors can upload their data file to the admin as a simple bulk data import. For my purposes, this was used for map coordinates displaying multiple pins and editors already have an auto-generated CSV file. So the aim was to prevent them from having to manually input new data each time it was updated.
Here's what I came up with:
In your model:
# Add a file upload field to your model. Uses built-in Documents section.
my_file = models.ForeignKey(
get_document_model(),
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='my_file',
verbose_name='Data File',
help_text="Select a CSV file or upload one if you haven't already.",
)
# Read and parse that file...
def get_file_contents(self):
if self.my_file:
# Open the file and read its contents
with self.my_file.file.open() as file:
# Read the content of the file
csv_content = file.read().decode('utf-8') # Decode bytes to string
# Use StringIO to treat the CSV content as a file-like object
csv_file = io.StringIO(csv_content)
# Read the CSV data into a dictionary
reader = csv.DictReader(csv_file)
# Convert the CSV data into a list of dictionaries
result = [row for row in reader]
return result
return None
Now in your template you can reference {{ page.get_file_contents }}
and use it in a for loop, etc.