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="******")
        user.save()
        profile = get_profile_model()(user=user)
        profile.save()

        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)
示例#2
0
    def get_queryset(self):
        params = self.request.GET
        key = 'users-{}'.format(hash(frozenset(params.items())))
        cache_ttl = 120
        result = cache.get(key)

        if not result:
            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)

            result_keys = [q.pk for q in queryset]
            related_field_name = get_profile_model()._meta.get_field(
                'user').related_query_name()

            result = User.objects.filter(
                pk__in=result_keys, public=True).prefetch_related(
                    related_field_name + '__skills', related_field_name +
                    '__causes').select_related(related_field_name)
            cache.set(key, result, cache_ttl)

        return result
示例#3
0
 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
示例#4
0
def create_sample_users():
  user1 = User(name="user one", email="*****@*****.**", password="******")
  user1.save()

  user2 = User(name="user two", email="*****@*****.**", password="******")
  user2.save()

  user3 = User(name="user three", email="*****@*****.**", password="******")
  user3.save()

  user4 = User(name="user four", email="*****@*****.**", password="******", public=False)
  user4.save()

  UserProfile = get_profile_model()
  profile1 = UserProfile(user=user1, full_name="user one", about="about one")
  profile1.save()
  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()
  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()
    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="******")
        user.save()
        profile = get_profile_model()(user=user)
        profile.save()

        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)
示例#6
0
  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()

    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()
    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")
示例#7
0
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_save', 'handle_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.skills.through,
        Organization.causes.through
    ]

    m2m_user = [
        get_profile_model().causes.through,
        get_profile_model().skills.through
    ]

    def setup(self):
        for item in self.attach_to:
            models.signals.post_save.connect(getattr(self, item[1]),
                                             sender=item[0])
            models.signals.post_delete.connect(getattr(self, item[2]),
                                               sender=item[0])

        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_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 """
        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
示例#8
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 []
示例#9
0
 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 []