-
Notifications
You must be signed in to change notification settings - Fork 1
Feature/likes and views #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Generated by Django 4.1.3 on 2023-01-21 14:14 | ||
|
|
||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ("projects", "0009_remove_project_short_description"), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AddField( | ||
| model_name="project", | ||
| name="views_count", | ||
| field=models.PositiveIntegerField(default=0), | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| from industries.models import Industry | ||
| from projects.models import Project, Achievement, Collaborator | ||
| from projects.validators import validate_project | ||
| from users.models import LikesOnProject | ||
| from vacancy.serializers import ProjectVacancyListSerializer | ||
|
|
||
|
|
||
|
|
@@ -65,6 +66,7 @@ class ProjectDetailSerializer(serializers.ModelSerializer): | |
| vacancies = ProjectVacancyListSerializer(many=True, read_only=True) | ||
| short_description = serializers.SerializerMethodField() | ||
| industry_id = serializers.IntegerField(required=False) | ||
| likes_count = serializers.SerializerMethodField(method_name="count_likes") | ||
|
|
||
| def validate(self, data): | ||
| super().validate(data) | ||
|
|
@@ -74,6 +76,9 @@ def validate(self, data): | |
| def get_short_description(cls, project): | ||
| return project.get_short_description() | ||
|
|
||
| def count_likes(self, project): | ||
| return LikesOnProject.objects.filter(project=project, is_liked=True).count() | ||
|
|
||
| def update(self, instance, validated_data): | ||
| instance = super().update(instance, validated_data) | ||
| instance.save() | ||
|
|
@@ -99,12 +104,20 @@ class Meta: | |
| "vacancies", | ||
| "datetime_created", | ||
| "datetime_updated", | ||
| "views_count", | ||
| "likes_count", | ||
| ] | ||
| read_only_fields = [ | ||
| "leader", | ||
| "views_count", | ||
| "datetime_created", | ||
| "datetime_updated", | ||
| ] | ||
| read_only_fields = ["leader"] | ||
|
|
||
|
|
||
| class ProjectListSerializer(serializers.ModelSerializer): | ||
| collaborators = serializers.SerializerMethodField(method_name="get_collaborators") | ||
| likes_count = serializers.SerializerMethodField(method_name="count_likes") | ||
| collaborator_count = serializers.SerializerMethodField( | ||
| method_name="get_collaborator_count" | ||
| ) | ||
|
|
@@ -120,6 +133,9 @@ def get_short_description(cls, project): | |
| def get_collaborator_count(cls, obj): | ||
| return len(obj.collaborator_set.all()) | ||
|
|
||
| def count_likes(self, obj): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. get_likes_count |
||
| return LikesOnProject.objects.filter(project=obj, is_liked=True).count() | ||
|
|
||
| def get_collaborators(self, obj): | ||
| max_collaborator_count = 4 | ||
| return CollaboratorSerializer( | ||
|
|
@@ -142,6 +158,7 @@ class Meta: | |
| "collaborators", | ||
| "vacancies", | ||
| "datetime_created", | ||
| "likes_count", | ||
| ] | ||
|
|
||
| read_only_fields = [ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |
| AchievementDetailSerializer, | ||
| ProjectCollaboratorSerializer, | ||
| ) | ||
| from users.models import LikesOnProject | ||
| from vacancy.models import VacancyResponse | ||
| from vacancy.serializers import VacancyResponseListSerializer | ||
|
|
||
|
|
@@ -79,6 +80,12 @@ class ProjectDetail(generics.RetrieveUpdateDestroyAPIView): | |
| permission_classes = [HasInvolvementInProjectOrReadOnly] | ||
| serializer_class = ProjectDetailSerializer | ||
|
|
||
| def retrieve(self, request, *args, **kwargs): | ||
| instance = self.get_object() | ||
| instance.increment_views_count() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Я думал, что мы можем сделать так, что один айпишник может увелчить кол-во просмотров на 1 раз в 5 минут. Т.е. добавить кеш ip-project, чтобы просмотры было накрутить проще, чем просто запустить скрипт который кидает запросы к апишке
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. чтобы *сложнее было наверно)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| serializer = self.get_serializer(instance) | ||
| return Response(serializer.data) | ||
|
|
||
| def put(self, request, pk, **kwargs): | ||
| # bootleg version of updating achievements via project | ||
| if request.data.get("achievements") is not None: | ||
|
|
@@ -100,6 +107,29 @@ def put(self, request, pk, **kwargs): | |
| return super(ProjectDetail, self).put(request, pk) | ||
|
|
||
|
|
||
| class SetLikeOnProject(APIView): | ||
| permission_classes = [IsAuthenticated] | ||
|
|
||
| def post(self, request, pk): | ||
| """ | ||
| Set like on project | ||
|
|
||
| --- | ||
|
|
||
| Args: | ||
| request: | ||
| pk - project id | ||
|
|
||
| Returns: | ||
| Response | ||
|
|
||
| """ | ||
| project = Project.objects.get(pk=pk) | ||
| LikesOnProject.objects.toggle_like(request.user, project) | ||
|
|
||
| return Response(ProjectListSerializer(project).data) | ||
|
|
||
|
|
||
| class ProjectCountView(generics.GenericAPIView): | ||
| queryset = Project.objects.get_projects_for_count_view() | ||
| serializer_class = ProjectListSerializer | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Generated by Django 4.1.3 on 2023-01-21 14:45 | ||
|
|
||
| from django.conf import settings | ||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ("projects", "0010_project_views_count"), | ||
| ("users", "0026_remove_member_preferred_industries_and_more"), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.CreateModel( | ||
| name="LikesOnProject", | ||
| fields=[ | ||
| ( | ||
| "id", | ||
| models.BigAutoField( | ||
| auto_created=True, | ||
| primary_key=True, | ||
| serialize=False, | ||
| verbose_name="ID", | ||
| ), | ||
| ), | ||
| ("like", models.BooleanField(default=True)), | ||
| ( | ||
| "project", | ||
| models.ForeignKey( | ||
| on_delete=django.db.models.deletion.CASCADE, | ||
| related_name="likes", | ||
| to="projects.project", | ||
| ), | ||
| ), | ||
| ( | ||
| "user", | ||
| models.ForeignKey( | ||
| on_delete=django.db.models.deletion.CASCADE, | ||
| related_name="likes_on_projects", | ||
| to=settings.AUTH_USER_MODEL, | ||
| ), | ||
| ), | ||
| ], | ||
| options={ | ||
| "verbose_name": "Лайк на проект", | ||
| "verbose_name_plural": "Лайки на проекты", | ||
| "unique_together": {("user", "project")}, | ||
| }, | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Generated by Django 4.1.3 on 2023-01-21 18:29 | ||
|
|
||
| from django.db import migrations | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ("users", "0027_likesonproject"), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.RenameField( | ||
| model_name="likesonproject", | ||
| old_name="like", | ||
| new_name="is_liked", | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| UserTypesView, | ||
| VerifyEmail, | ||
| LogoutView, | ||
| LikedProjectList, | ||
| ) | ||
|
|
||
| app_name = "users" | ||
|
|
@@ -24,6 +25,7 @@ | |
| ), # this url actually returns mentors, experts and investors | ||
| path("users/", UserList.as_view()), | ||
| path("users/projects/", UserProjectsList.as_view()), | ||
| path("users/liked/", LikedProjectList.as_view()), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. users/liked_projects будет понятнее |
||
| path("users/roles/", UserAdditionalRolesView.as_view()), | ||
| path("users/types/", UserTypesView.as_view()), | ||
| path("users/<int:pk>/", UserDetail.as_view()), | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.