def random_assign(self): """Return a randomly-selected object from the QuerySet. Requires that the QuerySet has been configured with an `assigned_object` field: the objects' related model field to be assigned. The objects' model must also have a `rand_cdf` field, the CDF probability of the object. """ assigned_object = getattr(self, 'assigned_object', None) if not assigned_object: raise TypeError("Assigned object field not set") assigned_object = getattr(assigned_object, 'name', assigned_object) for field in self.model._meta.fields: if field.name == assigned_object: assigned_class = field.related.parent_model break else: raise TypeError("Field {!r} not found on model {meta.app_label}.{meta.object_name}" .format(assigned_object, meta=self.model._meta)) options = self.values_list(assigned_object, 'rand_cdf') object_id = utils.random_assign(options) return assigned_class.objects.get(pk=object_id)
def assign_page_styles(visit, page_code, campaign, content=None): """Randomly assign a set of stylesheets to the page for the given campaign, and record that assignment. Database results are cached according to the `PAGE_STYLE_CACHE_TIMEOUT` setting. """ # Look up PageStyles: cache_key = 'campaignpagestylesets|{}|{}'.format(page_code, campaign.pk) options = django.core.cache.cache.get(cache_key) if options is None: # Retrieve from DB: campaign_page_style_sets = campaign.campaignpagestylesets.filter( page_style_set__page_styles__page__code=page_code, ).values_list('pk', 'page_style_set_id', 'rand_cdf').distinct() options = tuple(campaign_page_style_sets.iterator()) if options: # Store in cache django.core.cache.cache.set(cache_key, options, settings.PAGE_STYLE_CACHE_TIMEOUT) # Assign PageStyles: page_style_set_id = utils.random_assign( (page_style_set_id, rand_cdf) for (_pk, page_style_set_id, rand_cdf) in options ) # Record assignment: db.delayed_save.delay( models.relational.Assignment.make_managed( visit_id=visit.pk, campaign_id=campaign.pk, content_id=(content and content.pk), feature_row=page_style_set_id, chosen_from_rows=[pk for (pk, _page_style_set_id, _rand_cdf) in options], manager=campaign.campaignpagestylesets, ) ) cache_key = 'pagestyleset|{}'.format(page_style_set_id) hrefs = django.core.cache.cache.get(cache_key) if hrefs is None: page_style_set = models.relational.PageStyleSet.objects.get(pk=page_style_set_id) page_styles = page_style_set.page_styles.only('url') hrefs = tuple(page_style.href for page_style in page_styles.iterator()) django.core.cache.cache.set(cache_key, hrefs, settings.PAGE_STYLE_CACHE_TIMEOUT) return hrefs