def handle(self, *args, **options):
        # generate a name for the CSV file

        # determine the maximum answers to display per sheet
        max_answers = AnswerSheet.objects.get_max_answers()

        # open the output file
        filename = self.generate_file_name()
        outfile = self.get_file(filename)

        # create the csv writer
        writer = UnicodeWriter(outfile)

        # construct the header line
        header_line = ['User', 'msisdn', 'Questionnaire', 'Date Submitted',
                       'Status', 'Score']
        for idx in range(max_answers):
            header_line.append('Question %s' % (idx+1))
            header_line.append('Answer %s' % (idx+1))

        # write the header line
        writer.writerow(header_line)

        # loop through the database data to build the response
        qs = AnswerSheet.objects.all().order_by(
            'questionnaire', 'user')
        for sheet in qs:
            user = sheet.user
            msisdn = user.profile.mobile_number
            if msisdn is None:
                msisdn = u'Unknown'
            data = [user.username, msisdn,
                    sheet.questionnaire.title,
                    "%s" % sheet.date_created,
                    sheet.get_status_text(),
                    "%s" % sheet.calculate_score()
                    ]
            for answer in sheet.multichoiceanswer_set.all():
                data.append(answer.question.question_text)
                data.append(answer.chosen_option.option_text)
            writer.writerow(data)

        self.close_file(outfile)
    def handle(self, *args, **options):
        # generate a name for the CSV file

        # determine the maximum answers to display per sheet
        max_answers = AnswerSheet.objects.get_max_answers()

        # open the output file
        filename = self.generate_file_name()
        outfile = self.get_file(filename)

        # create the csv writer
        writer = UnicodeWriter(outfile)

        # construct the header line
        header_line = [
            'User', 'msisdn', 'Questionnaire', 'Date Submitted', 'Status',
            'Score'
        ]
        for idx in range(max_answers):
            header_line.append('Question %s' % (idx + 1))
            header_line.append('Answer %s' % (idx + 1))

        # write the header line
        writer.writerow(header_line)

        # loop through the database data to build the response
        qs = AnswerSheet.objects.all().order_by('questionnaire', 'user')
        for sheet in qs:
            user = sheet.user
            msisdn = user.profile.mobile_number
            if msisdn is None:
                msisdn = u'Unknown'
            data = [
                user.username, msisdn, sheet.questionnaire.title,
                "%s" % sheet.date_created,
                sheet.get_status_text(),
                "%s" % sheet.calculate_score()
            ]
            for answer in sheet.multichoiceanswer_set.all():
                data.append(answer.question.question_text)
                data.append(answer.chosen_option.option_text)
            writer.writerow(data)

        self.close_file(outfile)
Beispiel #3
0
    def csv_export(self, request):
        """ Return a CSV document of the competition entry and its user
            details
        """
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=competitionentries.csv'

        # create the csv writer with the response as the output file
        writer = UnicodeWriter(response)
        writer.writerow([
            'Competition ID', 'Competition', 'First Name', 'Last Name', 'Email Address',
            'Cell Number', 'Question', 'Answer File', 'Answer Option', 'Answer Text',
            'Has Correct Answer', 'Winner', 'Time Stamp'
        ])

        # This sucks big time. get_urls is cached upon first call, which means
        # it has no concept of a filter currently being applied to the
        # changelist. Grab the querystring from the referrer and re-use
        # changelist API to apply the filtering for us.
        try:
            dc, qs = request.META.get('HTTP_REFERER', '').split('?')
        except ValueError:
            qs = ''
        request.META['QUERY_STRING'] = qs
        queryset = self.get_changelist(request)(
            request, self.model, self.list_display, self.list_display_links,
            self.list_filter, self.date_hierarchy, self.search_fields,
            self.list_select_related, self.list_per_page,
            self.list_max_show_all, self.list_editable, self
        ).get_query_set(request)

        # select_related is too slow, so cache for fast lookups. This will not
        # scale indefinitely.
        competition_map = {}
        ids = queryset.distinct('competition').values_list(
            'competition_id', flat=True
        )
        for obj in Competition.objects.filter(id__in=ids):
            competition_map[obj.id] = obj

        # Looking up individual members is too slow, so cache for fast
        # lookups. This will not scale indefinitely.
        member_mobile_number_map = {}
        ids = queryset.distinct('user').values_list(
            'user_id', flat=True
        )
        for di in Member.objects.filter(id__in=ids).values(
            'id', 'mobile_number'
            ):
            member_mobile_number_map[di['id']] = di['mobile_number']

        for entry in queryset:
            competition = competition_map[entry.competition_id]
            entry.competition = competition
            row = [
                entry.competition.id,
                entry.competition.title,
                entry.user.first_name, entry.user.last_name,
                entry.user.email,
                member_mobile_number_map.get(entry.user_id, ''),
                entry.competition.question,
                entry.answer_file.name if entry.answer_file else '',
                entry.answer_option.text if entry.answer_option else '',
                entry.answer_text,
                entry.has_correct_answer(),
                entry.winner,
                entry.timestamp
            ]
            writer.writerow(['' if f is None else unicode(f) for f in row])  # '' instead of None

        return response