def test_ordering_by_relevance(self): """ Assert it's possible to order projects by relevance """ UserProfile = get_profile_model() user = User(name="b", email="*****@*****.**", password="******") user.save(object_channel="default") self.client.force_authenticate(user=user) response = self.client.get(reverse("search-projects-list") + "?ordering=-relevance,-created_date", format="json") self.assertEqual(response.status_code, 200) profile = UserProfile(user=user) profile.save(object_channel="default") profile.causes.add(Cause.objects.get(pk=1)) profile.skills.add(Skill.objects.get(pk=1)) profile.skills.add(Skill.objects.get(pk=2)) profile.causes.add(Cause.objects.get(pk=3)) response = self.client.get(reverse("search-projects-list") + "?ordering=-relevance,-created_date", format="json") self.assertEqual(str(response.data["results"][0]["name"]), "test project3") self.assertEqual(str(response.data["results"][1]["name"]), "test project") self.assertEqual(str(response.data["results"][2]["name"]), "test project2")
def update(self, instance, data): ProfileModel = get_profile_model() profile_data = data.pop('profile', None) if profile_data: has_profile=False try: if instance.profile: has_profile=True else: has_profile=False except models.UserProfile.DoesNotExist: has_profile=False if has_profile: profile = instance.profile else: profile = ProfileModel(user=instance) profile.save(object_channel=self.context["request"].channel) profile_sr = get_profile_serializers()[0](profile, data=profile_data, partial=True) profile_sr.is_valid(raise_exception=True) profile = profile_sr.update(profile, profile_sr.validated_data) return super(UserUpdateSerializer, self).update(instance, data)
def handle_profile_delete(self, sender, instance, **kwargs): """ Custom handler for user profile delete """ try: self.handle_save(instance.user.__class__, instance.user) # we call save just as well except (get_profile_model().DoesNotExist): pass # just returns, instance already deleted from database
def profile(self): model = get_profile_model() related_field_name = model._meta.get_field('user').related_query_name() try: obj = getattr(self, related_field_name, None) if isinstance(obj, model): return obj else: return model.objects.get(user=self) except model.DoesNotExist: return None
def test_index_on_delete(self): """ Test user index gets updated when a project is created or updated """ self.assertTrue(SearchQuerySet().models(User).all().count() == 0) user = User.objects.create_user(email="*****@*****.**", password="******", object_channel="default") profile = get_profile_model()(user=user) profile.save(object_channel="default") self.assertTrue(SearchQuerySet().models(User).all().count() == 1) profile.delete() self.assertTrue(SearchQuerySet().models(User).all().count() == 1) user.delete() self.assertTrue(SearchQuerySet().models(User).all().count() == 0)
def create_sample_users(): user1 = User(name="user one", email="*****@*****.**", password="******") user1.save(object_channel="default") user2 = User(name="user two", email="*****@*****.**", password="******") user2.save(object_channel="default") user3 = User(name="user three", email="*****@*****.**", password="******") user3.save(object_channel="default") user4 = User(name="user four", email="*****@*****.**", password="******", public=False) user4.save(object_channel="default") user5 = User(name="user five", email="*****@*****.**", password="******") user5.save(object_channel="test-channel") UserProfile = get_profile_model() profile1 = UserProfile(user=user1, full_name="user one", about="about one") profile1.save(object_channel="default") profile1.causes.add(Cause.objects.get(pk=1)) profile1.causes.add(Cause.objects.get(pk=2)) profile1.skills.add(Skill.objects.get(pk=1)) profile1.skills.add(Skill.objects.get(pk=2)) profile2 = UserProfile(user=user2, full_name="user two", about="about two") profile2.save(object_channel="default") profile2.causes.add(Cause.objects.get(pk=1)) profile2.causes.add(Cause.objects.get(pk=3)) profile2.skills.add(Skill.objects.get(pk=1)) profile2.skills.add(Skill.objects.get(pk=3)) profile3 = UserProfile(user=user3, full_name="user three", about="about three") profile3.save(object_channel="default")
def get_queryset(self): params = self.request.GET cause = params.get('cause', None) skill = params.get('skill', None) name = params.get('name', None) queryset = SearchQuerySet().models(User) queryset = filters.by_skills(queryset, skill) queryset = filters.by_causes(queryset, cause) queryset = filters.by_name(queryset, name) queryset = queryset.filter(channel=self.request.channel) result_keys = [q.pk for q in queryset] related_field_name = get_profile_model()._meta.get_field( 'user').related_query_name() result = User.objects.order_by('-pk').filter( pk__in=result_keys, public=True).prefetch_related( related_field_name + '__skills', related_field_name + '__causes').select_related(related_field_name) return result
def test_index_on_create_and_update(self): """ Test user index gets updated when a project is created or updated """ cause = Cause.objects.all().order_by('pk').first() skill = Skill.objects.all().order_by('pk').first() self.assertTrue(SearchQuerySet().models(User).all().count() == 0) user = User.objects.create_user(email="*****@*****.**", password="******", object_channel="default") profile = get_profile_model()(user=user) profile.save(object_channel="default") self.assertTrue(SearchQuerySet().models(User).filter(skills=skill.pk).count() == 0) profile.skills.add(skill) self.assertTrue(SearchQuerySet().models(User).filter(skills=skill.pk).count() == 1) self.assertTrue(SearchQuerySet().models(User).filter(causes=cause.pk).count() == 0) profile.causes.add(cause) self.assertTrue(SearchQuerySet().models(User).filter(causes=cause.pk).count() == 1) profile.skills.clear() profile.causes.clear() self.assertTrue(SearchQuerySet().models(User).filter(skills=skill.pk).count() == 0) self.assertTrue(SearchQuerySet().models(User).filter(causes=cause.pk).count() == 0)
def prepare_skills(self, obj): try: if obj.profile: return [skill.id for skill in obj.profile.skills.all()] except get_profile_model().DoesNotExist: # pragma: no cover return []
def prepare_causes(self, obj): try: if obj.profile: return [cause.id for cause in obj.profile.causes.all()] except get_profile_model().DoesNotExist: # pragma: no cover return []
class Meta: model = get_profile_model() fields = [ 'full_name', 'about', 'skills', 'causes', 'gender', 'address', 'hidden_address', 'birthday_date' ]
class Meta: model = get_profile_model() fields = ['full_name', 'skills', 'causes', 'gender']
class TiedModelRealtimeSignalProcessor(signals.BaseSignalProcessor): """ TiedModelRealTimeSignalProcessor handles updates to a index tied to a model We need to be able to detect changes to a model a rebuild another index, such as detecting changes to GoogleAddress and updating the index for projects and organizations. """ attach_to = { Project: ('handle_project_save', 'handle_project_delete'), Organization: ('handle_save', 'handle_delete'), User: ('handle_save', 'handle_delete'), get_profile_model(): ('handle_profile_save', 'handle_profile_delete'), GoogleAddress: ('handle_address_save', 'handle_address_delete'), Job: ('handle_job_and_work_save', 'handle_job_and_work_delete'), Work: ('handle_job_and_work_save', 'handle_job_and_work_delete'), } m2m = [ Project.causes.through, Project.categories.through, Project.skills.through, Organization.causes.through ] m2m_user = [ get_profile_model().causes.through, get_profile_model().skills.through ] def setup(self): for model, functions in self.attach_to.items(): models.signals.post_save.connect(getattr(self, functions[0]), sender=model) models.signals.post_delete.connect(getattr(self, functions[1]), sender=model) for item in self.m2m: models.signals.m2m_changed.connect(self.handle_m2m, sender=item) for item in self.m2m_user: models.signals.m2m_changed.connect(self.handle_m2m_user, sender=item) # never really called def teardown(self): # pragma: no cover for item in self.attach_to: models.signals.post_save.disconnect(getattr(self, item[1]), sender=item[0]) models.signals.post_delete.disconnect(getattr(self, item[2]), sender=item[0]) for item in self.m2m: models.signals.m2m_changed.disconnect(self.handle_m2m, sender=item) for item in self.m2m_user: models.signals.m2m_changed.disconnect(self.handle_m2m_user, sender=item) def handle_project_save(self, sender, instance, **kwargs): """ Custom handler for project save """ # We reindex organization, as it index information about projects(projects categories) if instance.organization: self.handle_save(instance.organization.__class__, instance.organization) self.handle_save(instance.__class__, instance) def handle_project_delete(self, sender, instance, **kwargs): """ Custom handler for project delete """ self.handle_delete(instance.__class__, instance) if instance.organization: self.handle_save(instance.organization.__class__, instance.organization) def handle_address_save(self, sender, instance, **kwargs): """ Custom handler for address save """ objects = self.find_associated_with_address(instance) for obj in objects: self.handle_save(obj.__class__, obj) # this function is never really called on sqlite dbs def handle_address_delete(self, sender, instance, **kwargs): """ Custom handler for address delete """ objects = self.find_associated_with_address(instance) # this is not called as django will delete associated project/address # triggering handle_delete for obj in objects: # pragma: no cover self.handle_delete(obj.__class__, obj) def handle_job_and_work_save(self, sender, instance, **kwargs): """ Custom handler for job and work save """ self.handle_save(instance.project.__class__, instance.project) def handle_job_and_work_delete(self, sender, instance, **kwargs): """ Custom handler for job and work delete """ self.handle_delete(instance.project.__class__, instance.project) def handle_profile_save(self, sender, instance, **kwargs): """ Custom handler for user profile save """ self.handle_save(instance.user.__class__, instance.user) def handle_profile_delete(self, sender, instance, **kwargs): """ Custom handler for user profile delete """ try: self.handle_save(instance.user.__class__, instance.user) # we call save just as well except (get_profile_model().DoesNotExist): pass # just returns, instance already deleted from database def handle_m2m(self, sender, instance, **kwargs): """ Handle many to many relationships """ if self.attach_to.get(instance.__class__, None): getattr(self, self.attach_to[instance.__class__][0])(instance.__class__, instance) else: self.handle_save(instance.__class__, instance) def handle_m2m_user(self, sender, instance, **kwargs): """ Handle many to many relationships for user field """ self.handle_save(instance.user.__class__, instance.user) def find_associated_with_address(self, instance): """ Returns list with projects and organizations associated with given address """ objects = [] objects += list(Project.objects.filter(address=instance)) objects += list(Organization.objects.filter(address=instance)) return objects
import six import sys from social_django.strategy import DjangoStrategy from django.contrib.auth import get_user_model from django.core.exceptions import FieldError from ovp.apps.users.models.profile import get_profile_model User = get_user_model() UserProfile = get_profile_model() class OVPDjangoStrategy(DjangoStrategy): def get_kwargs(self, **kwargs): data = {"email": kwargs["email"]} get_kwargs = dict(data) create_kwargs = dict(data) # Get kwargs get_kwargs["channel__slug"] = self.request.channel # Create kwargs create_kwargs["object_channel"] = self.request.channel return get_kwargs, create_kwargs def create_user(self, *args, **kwargs): get_kwargs, create_kwargs = self.get_kwargs(**kwargs) try: user = super(OVPDjangoStrategy, self).create_user(*args, **create_kwargs) UserProfile.objects.create(user=user, object_channel=self.request.channel)