Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add skills and engagement_level to csv export

  • Loading branch information...
commit 11c0c487fe5f8927a6587b54b4b047267745f389 1 parent dc63349
@rmarianski rmarianski authored
Showing with 20 additions and 6 deletions.
  1. +20 −6 search/
26 search/
@@ -952,17 +952,28 @@ def safe_encode(value):
return str(value)
-def user_to_csv_row(user, fields):
+def user_to_csv_row(user, fields, field_fns):
row = []
for field in fields:
- value = getattr(user, field, '') or ''
- if callable(value):
- value = value()
+ field_fn = field_fns.get(field, None)
+ if field_fn is not None:
+ value = field_fn(user)
+ else:
+ value = getattr(user, field, '') or ''
+ if callable(value):
+ value = value()
value = safe_encode(value)
return row
+def corefield_value(field_name):
+ def get_corefield(user):
+ values = [f.value for f in user.fields.all() if == field_name]
@ejucovy Owner
ejucovy added a note

This function is inefficient -- I believe that user.fields.all() will trigger a new DB query each time it's called (Django doesn't cache these things, at least I don't think it does) so that's a new query each time corefield_value's inner function is called.

But even worse than that, it's doing this for each user in the list; the context here is a CSV export of multiple users, so for a list with 100 users, that's like 200 extra DB queries.

Instead of this function, we should use stuff like queryset.extra(select={"skills": "select `value` from `core_userfield` where `core_userfield`.`name` = "skills" and `core_userfield`.`parent_id` = `core_user`.`id`}) -- that way these attributes will land on each CoreUser object as a result of the initial SELECT * FROM core_user query. See L656 for an example of where we're already doing this in the underlying _search function (which is probably where this should happen too)

(Or alternatively we could do a single select on all core_userfields that match our current list of users, and shuffle them onto the right users and the right attributes in Python code: CoreUserfield.objects.filter(parent__id__in=list_of_core_user_ids); presumably as the number of distinct fields we collect grows, that'll become the more efficient choice.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ return ','.join(values)
+ return get_corefield
@@ -970,7 +981,10 @@ def search_csv(request):
user_fields = ['first_name', 'last_name', 'email',
'address1', 'address2', 'city', 'state', 'region',
'postal', 'zip', 'country',
- 'source', 'subscription_status', 'phone', 'campus']
+ 'source', 'subscription_status', 'phone', 'campus',
+ 'skills', 'engagement_level']
+ field_fns = dict(skills=corefield_value('skills'),
+ engagement_level=corefield_value('engagement_level'))
fields = request.GET.getlist('fields')
if not fields:
keyvals = []
@@ -986,7 +1000,7 @@ def search_csv(request):
users = _search(request)['users']
for user in users:
- row = user_to_csv_row(user, fields)
+ row = user_to_csv_row(user, fields, field_fns)
response = HttpResponse(buffer.getvalue())
response['Content-Type'] = 'text/csv'
Please sign in to comment.
Something went wrong with that request. Please try again.