I’ve added an export CSV function to my page. I would like it to retain the filtered data that is rendered when the user submits the form, however, the export is downloading all rows rather than the filtered rows. The view is returning the correct filtered rows, but not when exporting.
Views
class PropertyListView(View):
def get(self, request):
form = PropertyFilterForm()
context = {
'form': form,
}
return render(request, 'listings/property-list.html', context)
def post(self, request):
form = PropertyFilterForm(request.POST)
if form.is_valid():
start_date = form.cleaned_data['start_date']
end_date = form.cleaned_data['end_date']
suburb = form.cleaned_data['suburb']
state = form.cleaned_data['state']
postcode = form.cleaned_data['postcode']
listings = PropertyListing.objects.all().order_by('-date_sold')
if start_date and end_date:
listings = listings.filter(date_sold__range=[start_date, end_date])
if suburb:
listings = listings.filter(suburb__icontains=suburb)
if state:
listings = listings.filter(state__icontains=state)
if postcode:
listings = listings.filter(postcode__icontains=postcode)
context = {
'form': form,
'listings': listings,
}
# Check if export to CSV is requested
if 'export_csv' in request.POST:
response = self.export_to_csv()
return response
return render(request, 'listings/property-list.html', context)
# Form is invalid, render the form again
context = {
'form': form,
}
return render(request, 'listings/property-list.html', context)
def export_csv(request):
form = PropertyFilterForm(request.POST)
if form.is_valid():
start_date = form.cleaned_data['start_date']
end_date = form.cleaned_data['end_date']
suburb = form.cleaned_data['suburb']
state = form.cleaned_data['state']
postcode = form.cleaned_data['postcode']
listings = PropertyListing.objects.all().order_by('-date_sold')
if start_date and end_date:
listings = listings.filter(date_sold__range=[start_date, end_date])
if suburb:
listings = listings.filter(suburb__icontains=suburb)
if state:
listings = listings.filter(state__icontains=state)
if postcode:
listings = listings.filter(postcode__icontains=postcode)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="property_listings.csv"'
writer = csv.writer(response)
writer.writerow(['ID', 'Date Sold', 'Sold By', 'Price Guide', 'Price Guide Info', 'Address',
'# of Beds', '# of Baths', '# of Parking', 'Size (m²)', 'House Type', 'Inspection',
'Full Address', 'Listing Type', 'Suburb', 'State', 'Postcode', 'Profile'])
for listing in listings:
writer.writerow([listing.id, listing.date_sold, listing.sold_by, listing.price_guide,
listing.price_guide_info, listing.address1, listing.num_of_beds, listing.num_of_baths,
listing.num_of_parking, listing.size_msq, listing.house_type, listing.inspection,
listing.full_address, listing.listing_type, listing.suburb, listing.state,
listing.postcode, listing.profile])
return response
else:
return HttpResponseBadRequest()
FORMS
class PropertyFilterForm(forms.Form):
start_date = forms.ChoiceField(label='Start Date', choices=[], required=False)
end_date = forms.ChoiceField(label='End Date', choices=[], required=False)
suburb = forms.ChoiceField(label='Suburb', choices=[], required=False)
state = forms.ChoiceField(label='State', choices=[], required=False)
postcode = forms.ChoiceField(label='Postcode', choices=[], required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['start_date'].choices = self.get_date_choices()
self.fields['end_date'].choices = self.get_date_choices()
self.fields['suburb'].choices = self.get_suburb_choices()
self.fields['state'].choices = self.get_state_choices()
self.fields['postcode'].choices = self.get_postcode_choices()
def get_date_choices(self):
date_choices = PropertyListing.objects.values_list('date_sold', flat=True).distinct()
formatted_choices = [
(date.strftime('%Y-%m-%d'), date.strftime('%Y-%m-%d'))
for date in date_choices
]
return formatted_choices
def get_suburb_choices(self):
return [(suburb, suburb) for suburb in PropertyListing.objects.values_list('suburb', flat=True).distinct()]
def get_state_choices(self):
states = PropertyListing.objects.values_list('state', flat=True).distinct()
return [(state, state) for state in states]
def get_postcode_choices(self):
return [(postcode, postcode) for postcode in PropertyListing.objects.values_list('postcode', flat=True).distinct()]
URLS
from django.urls import path
from .views import PropertyListView, export_csv
app_name = 'listings'
urlpatterns = [
path('property-list/', PropertyListView.as_view(), name='property-list'),
path('export-csv/', export_csv, name='export-csv'),
]
HTML
<div style="display: flex; justify-content: center;">
<a href="{% url 'listings:export-csv' %}" class="btn btn-primary">Export to CSV</a>
</div>