Last active
May 17, 2017 14:03
-
-
Save lostb1t/bf7562c400d0512094e0c4b83e1fa76b to your computer and use it in GitHub Desktop.
ModelCollector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UserSalesCollector(ModelCollector): | |
fields = [ | |
'uuid', | |
'date_joined', | |
'birthdate.year', | |
'zip4', | |
'userrecord.num_orders', | |
'userrecord.total_spent', | |
'userrecord.num_product_views', | |
'loyaltycard' | |
] | |
model_class = User | |
def get_queryset(self, start_date, end_date): | |
qs = super(UserSalesCollector, self).get_queryset(start_date, end_date) | |
return qs.select_related('userrecord').order_by('id') | |
""" | |
Callbacks | |
""" | |
def get_loyaltycard(self, item): | |
return 'JA' if item.loyaltycard else 'NEE' | |
def get_zip4(self, item, value): | |
address = item.addresses.filter(is_default_for_billing=True).last() | |
if address: | |
return address.postcode[:4] | |
return self.default_value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ModelCollector(Collector): | |
""" | |
Collector for Django models. | |
fields:: List of fields to collect. | |
Either a string of the field name, ex: | |
fields = ['pk', 'name'] | |
or a tuple with a custom label, ex: | |
fields = [('pk', 'Identifier'), name] | |
model_class:: Django model class | |
use_verbose_name:: Use the verbose name of the field for the header | |
""" | |
fields = [] | |
model_class = None | |
use_verbose_name = True | |
def get_header(self): | |
header = [] | |
for field in self.fields: | |
header.append(self._resolve_label(field, self.model_class)) | |
return header | |
def get_item(self, obj): | |
item = [] | |
for field in self.fields: | |
field_name, label = self._extract_field(field) | |
item.append(self._resolve_value(field_name, obj)) | |
return item | |
def get_items(self, start_date, end_date): | |
items = [] | |
for obj in self.get_queryset(start_date, end_date): | |
items.append(self.get_item(obj)) | |
return items | |
def get_queryset(self, start_date, end_date): | |
return self.model_class.objects.all() | |
""" | |
Internals | |
""" | |
def _resolve_value(self, field_name, obj): | |
field_tree = field_name.split('.') | |
callback_function = "get_{}".format(('_').join(field_tree)) | |
try: | |
return getattr(self, callback_function)(obj) | |
except: | |
value = self._resolve_value_from_field(field_name, obj) | |
return value | |
def _resolve_value_from_field(self, field_name, value): | |
field_tree = field_name.split('.') | |
for field_name in field_tree: | |
value = self._get_value(field_name, value) | |
return value | |
def _get_value(self, field_name, obj): | |
try: | |
value = getattr(obj, field_name) | |
except: | |
value = self.default_value | |
return value | |
def _resolve_label(self, field, model_class): | |
label = None | |
if self._is_list(field): | |
# custom label | |
label = list(field)[1] | |
elif self.use_verbose_name: | |
# resolve verbose name | |
label = self._resolve_verbose_name(field, model_class) | |
if not label: | |
label = field | |
return label | |
def _resolve_verbose_name(self, field, model_class): | |
verbose_name = None | |
field_tree = field.split('.') | |
l = len(field_tree) | |
i = 0 | |
for field in field_tree: | |
i += 1 | |
labell = self._get_verbose_name(field, model_class) | |
if labell: | |
verbose_name = labell | |
if i < l: | |
f = model_class._meta.get_field(field) | |
try: | |
model_class = f.related_model | |
labell = self._get_verbose_name(field_tree[i], model_class) | |
if labell: | |
verbose_name = labell | |
except: | |
pass | |
return verbose_name | |
def _get_verbose_name(self, field, model_class): | |
try: | |
label = model_class._meta.get_field(field).verbose_name | |
except: | |
label = None | |
return label | |
def _extract_field(self, field): | |
if self._is_list(field): | |
field_name, label = list(field) | |
else: | |
field_name = field | |
label = None | |
return field_name, label | |
def _is_list(self, field): | |
if isinstance(field, (list, tuple)): | |
return True | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment