Django View

CSV Download

Tip

To test this view… see Django Testing.

import csv
from django.http import HttpResponse

def _get_response(file_name):
    """Create the HttpResponse object with the appropriate CSV header."""
    response = HttpResponse(content_type="text/csv")
    response["Content-Disposition"] = 'attachment; filename="{}"'.format(
        file_name
    )
    return response


def _report(response):
    csv_writer = csv.writer(response, dialect="excel")
    csv_writer.writerow(("name", "email", "consent"))
    qs = Consent.objects.current().order_by("-date_updated", "pk")
    for x in qs:
        l = [x.name, x.email, x.consent_given]
        csv_writer.writerow(l)
    return response


@staff_member_required
def report_download(request, pk):
    today = timezone.now()
    consent = Consent.objects.get(pk=pk)
    file_name = "consent-{}-{}-{:02d}-{:02d}.csv".format(
        consent.slug, today.year, today.month, today.day
    )
    response = _get_response(file_name)
    return _report(response)

UpdateView not DeleteView

Warning

We don’t delete data (unless there is a specific requirement for it).

To delete an object, use an UpdateView to set_deleted e.g:

class ContactDeleteView(
    LoginRequiredMixin, StaffuserRequiredMixin, BaseMixin, UpdateView):

    template_name = "dash/contact_confirm_delete.html"
    model = Contact
    form_class = ContactEmptyForm

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.set_deleted(self.request.user)
        messages.info(self.request, "Deleted {}".format(self.object.name))
        return HttpResponseRedirect(self.get_success_url())

    def get_success_url(self):
        return reverse("dash.contact.detail", args=[self.object.pk])

Tip

To add the set_deleted field to a model, see TimedCreateModifyDeleteModel

The ListView should display only current contacts:

class ContactListView(
    LoginRequiredMixin, StaffuserRequiredMixin, BaseMixin, ListView
):
    def get_queryset(self):
        return Contact.objects.current()

You can create a current method on the model manager e.g:

class ContactManager(models.Manager):
    def current(self):
        return self.model.objects.exclude(deleted=True)