List fans and starred projects

List project fans:

     /projects/<project id>/fans
     /projects/<project id>/fans/<user id>

List user starred projects:

     /users/<user id>/starred
     /users/<user id>/starred/<project id>

Also a "star" field with the stars count of a project is included in the
project detail and list responses.
remotes/origin/enhancement/email-actions
Anler Hp 2014-05-27 17:24:57 +02:00
parent b56dfe7cf5
commit 34f0dd6f76
9 changed files with 128 additions and 7 deletions

View File

@ -324,3 +324,21 @@ class ProjectTemplateViewSet(ModelCrudViewSet):
def get_queryset(self):
return models.ProjectTemplate.objects.all()
class FansViewSet(ModelCrudViewSet):
serializer_class = serializers.FanSerializer
list_serializer_class = serializers.FanSerializer
permission_classes = (IsAuthenticated,)
def get_queryset(self):
return stars.get_fans(self.kwargs.get("project_id"))
class StarredViewSet(ModelCrudViewSet):
serializer_class = serializers.StarredSerializer
list_serializer_class = serializers.StarredSerializer
permission_classes = (IsAuthenticated,)
def get_queryset(self):
return stars.get_starred(self.kwargs.get("user_id"))

View File

@ -19,7 +19,7 @@ from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from taiga.base.serializers import PickleField, JsonField
from taiga.users.models import Role
from taiga.users.models import Role, User
from . import models
@ -84,6 +84,7 @@ class ProjectMembershipSerializer(serializers.ModelSerializer):
class ProjectSerializer(serializers.ModelSerializer):
tags = PickleField(required=False)
stars = serializers.IntegerField(source="stars.count")
class Meta:
model = models.Project
@ -150,3 +151,17 @@ class ProjectTemplateSerializer(serializers.ModelSerializer):
class Meta:
model = models.ProjectTemplate
class FanSerializer(serializers.ModelSerializer):
full_name = serializers.CharField(source='get_full_name', required=False)
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name', 'full_name')
class StarredSerializer(serializers.ModelSerializer):
class Meta:
model = models.Project
fields = ['id', 'name', 'slug']

View File

@ -1 +1 @@
from .services import star, unstar
from .services import star, unstar, get_fans, get_starred

View File

@ -24,7 +24,7 @@ class Fan(models.Model):
class Stars(models.Model):
project = models.OneToOneField("projects.Project", null=False, blank=False,
verbose_name=_("project"))
related_name="stars", verbose_name=_("project"))
count = models.PositiveIntegerField(null=False, blank=False, default=0,
verbose_name=_("count"))

View File

@ -45,11 +45,23 @@ def get_stars(project):
return Stars.objects.filter(project=project).count
def get_fans(project):
def get_fans(project_or_id):
"""Get the fans a project have."""
return get_user_model().objects.filter(fans__project=project)
qs = get_user_model().objects.get_queryset()
if isinstance(project_or_id, int):
qs = qs.filter(fans__project_id=project_or_id)
else:
qs = qs.filter(fans__project=project_or_id)
return qs
def get_starred_projects(user):
def get_starred(user_or_id):
"""Get the projects an user has starred."""
return Project.objects.filter(fans__user=user)
qs = Project.objects.get_queryset()
if isinstance(user_or_id, int):
qs = qs.filter(fans__user_id=user_or_id)
else:
qs = qs.filter(fans__user=user_or_id)
return qs

View File

@ -59,9 +59,13 @@ from taiga.projects.api import IssueTypeViewSet
from taiga.projects.api import PriorityViewSet
from taiga.projects.api import SeverityViewSet
from taiga.projects.api import ProjectTemplateViewSet
from taiga.projects.api import FansViewSet
from taiga.projects.api import StarredViewSet
router.register(r"roles", RolesViewSet, base_name="roles")
router.register(r"projects", ProjectViewSet, base_name="projects")
router.register(r"projects/(?P<project_id>\d+)/fans", FansViewSet, base_name="project-fans")
router.register(r"users/(?P<user_id>\d+)/starred", StarredViewSet, base_name="user-starred")
router.register(r"project-templates", ProjectTemplateViewSet, base_name="project-templates")
router.register(r"memberships", MembershipViewSet, base_name="memberships")
router.register(r"invitations", InvitationViewSet, base_name="invitations")

View File

@ -18,6 +18,8 @@ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Permission
from rest_framework import serializers
from taiga.projects.models import Project
from .models import User, Role

View File

@ -164,3 +164,10 @@ class FanFactory(Factory):
project = factory.SubFactory("tests.factories.ProjectFactory")
user = factory.SubFactory("tests.factories.UserFactory")
class StarsFactory(Factory):
FACTORY_FOR = taiga.projects.stars.models.Stars
project = factory.SubFactory("tests.factories.ProjectFactory")
count = 0

View File

@ -52,3 +52,66 @@ def test_project_member_unstar_project(client):
response = client.post(url)
assert response.status_code == 200
def test_list_project_fans(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user)
fan = f.FanFactory.create(project=project)
url = reverse("project-fans-list", args=(project.id,))
client.login(user)
response = client.get(url)
assert response.status_code == 200
assert response.data[0]['id'] == fan.user.id
def test_get_project_fan(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user)
fan = f.FanFactory.create(project=project)
url = reverse("project-fans-detail", args=(project.id, fan.user.id))
client.login(user)
response = client.get(url)
assert response.status_code == 200
assert response.data['id'] == fan.user.id
def test_list_user_starred_projects(client):
user = f.UserFactory.create()
fan = f.FanFactory.create(user=user)
url = reverse("user-starred-list", args=(user.id,))
client.login(user)
response = client.get(url)
assert response.status_code == 200
assert response.data[0]['id'] == fan.project.id
def test_get_user_starred_project(client):
user = f.UserFactory.create()
fan = f.FanFactory.create(user=user)
url = reverse("user-starred-detail", args=(user.id, fan.project.id))
client.login(user)
response = client.get(url)
assert response.status_code == 200
assert response.data['id'] == fan.project.id
def test_get_project_stars(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user)
f.StarsFactory.create(project=project, count=5)
url = reverse("projects-detail", args=(project.id,))
client.login(user)
response = client.get(url)
assert response.status_code == 200
assert response.data['stars'] == 5