How to do it...

Admin actions are functions that take three arguments, as follows:

  • The current ModelAdmin value
  • The current HttpRequest value
  • The QuerySet value, which contains the selected items

Perform the following steps to create a custom admin action to export a spreadsheet:

  1. Create a ColumnConfig class for spreadsheet column configuration in the admin.py file of the products app, as follows:
# myproject/apps/products/admin.py
from openpyxl import Workbook
from openpyxl.styles import Alignment, NamedStyle, builtins
from openpyxl.styles.numbers import FORMAT_NUMBER
from openpyxl.writer.excel import save_virtual_workbook

from django.http.response import HttpResponse
from django.utils.translation import ugettext_lazy as _
from ordered_model.admin import OrderedTabularInline, OrderedInlineModelAdminMixin

# other imports…

class ColumnConfig:
def __init__(
self,
heading,
width=None,
heading_style="Headline 1",
style="Normal Wrapped",
number_format=None,
):
self.heading = heading
self.width = width
self.heading_style = heading_style
self.style = style
self.number_format = number_format
  1. Then, in the same file, create the export_xlsx() function:
def export_xlsx(modeladmin, request, queryset):
wb = Workbook()
ws = wb.active
ws.title = "Products"

number_alignment = Alignment(horizontal="right")
wb.add_named_style(
NamedStyle(
"Identifier", alignment=number_alignment,
number_format=FORMAT_NUMBER
)
)
wb.add_named_style(
NamedStyle("Normal Wrapped",
alignment=Alignment(wrap_text=True))
)

column_config = {
"A": ColumnConfig("ID", width=10, style="Identifier"),
"B": ColumnConfig("Title", width=30),
"C": ColumnConfig("Description", width=60),
"D": ColumnConfig("Price", width=15, style="Currency",
number_format="#,##0.00 €"),
"E": ColumnConfig("Preview", width=100, style="Hyperlink"),
}

# Set up column widths, header values and styles
for col, conf in column_config.items():
ws.column_dimensions[col].width = conf.width

column = ws[f"{col}1"]
column.value = conf.heading
column.style = conf.heading_style

# Add products
for obj in queryset.order_by("pk"):
project_photos = obj.productphoto_set.all()[:1]
url = ""
if project_photos:
url = project_photos[0].photo.url

data = [obj.pk, obj.title, obj.description, obj.price, url]
ws.append(data)

row = ws.max_row
for row_cells in ws.iter_cols(min_row=row, max_row=row):
for cell in row_cells:
conf = column_config[cell.column_letter]
cell.style = conf.style
if conf.number_format:
cell.number_format = conf.number_format

mimetype = "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet"
charset = "utf-8"
response = HttpResponse(
content=save_virtual_workbook(wb),
content_type=f"{mimetype}; charset={charset}",
charset=charset,
)
response["Content-Disposition"] = "attachment;
filename=products.xlsx"
return response

export_xlsx.short_description = _("Export XLSX")
  1. Then, add the actions setting to ProductAdmin, as follows:
@admin.register(Product)
class ProductAdmin(OrderedInlineModelAdminMixin, admin.ModelAdmin):
# …
actions = [export_xlsx]
# …
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset