Skip to content

Commit

Permalink
✨(models) issue-196: add models and endpoints to user wishlist
Browse files Browse the repository at this point in the history
This commit is the first part of the issue 196 (feature wishlist)
This commit add:
* model CourseWish that link a User and a Course
* endpoints to use this new model, according to the auth User
        * GET wish list (can be filtered by course_code)
        * GET a wish
        * POST a wish
        * DELETE a wish
  • Loading branch information
MorganeAD committed Feb 28, 2023
1 parent c1c01c3 commit 1aa2177
Show file tree
Hide file tree
Showing 10 changed files with 542 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ and this project adheres to

- Add synchronization for course runs
- Add make dbshell cmd to access database in cli
- Add model and endpoints for wishlist feature

### Fixed

Expand Down
11 changes: 11 additions & 0 deletions src/backend/joanie/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,14 @@ class AddressAdmin(admin.ModelAdmin):
"is_main",
"owner",
)


@admin.register(models.CourseWish)
class CourseWishAdmin(admin.ModelAdmin):
"""Admin class for the CourseWish model"""

list_display = (
"course",
"owner",
)
readonly_fields = ("id",)
46 changes: 46 additions & 0 deletions src/backend/joanie/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,49 @@ def download(self, request, pk=None): # pylint: disable=no-self-use, invalid-na
response["Content-Disposition"] = f"attachment; filename={pk}.pdf;"

return response


class CourseWishViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet,
):
"""
API view allows to get all wishlists or create a new one for a user.
GET /api/wishlist/
Return list of all wishes for a user
GET /api/wishlist/?course_code=<course_code>
Return list of wishes for a user filter by the course_code
GET /api/wishlist/<course_wish_id>/
Return selected wish
POST /api/wishlist/ with expected data:
- course: str course_code
Return new wish just created
DELETE /api/wishlist/<course_wish_id>/
Delete selected wish
"""

lookup_field = "id"
serializer_class = serializers.CourseWishSerializer
permission_classes = [permissions.IsAuthenticated]

def get_queryset(self):
"""Custom queryset to get user addresses"""
user = User.update_or_create_from_request_user(request_user=self.request.user)
queryset = user.wishlists.all()
course_code = self.request.query_params.get("course_code")
if course_code is not None:
queryset = queryset.filter(course__code=course_code)
return queryset

def perform_create(self, serializer):
"""Create a new address for user authenticated"""
user = User.update_or_create_from_request_user(request_user=self.request.user)
serializer.save(owner=user)
10 changes: 10 additions & 0 deletions src/backend/joanie/core/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,13 @@ def certificate_definition(self):
Return the order product certificate definition.
"""
return self.order.product.certificate_definition


class CourseWishFactory(factory.django.DjangoModelFactory):
"""A factory to create an user wish"""

class Meta:
model = models.CourseWish

course = factory.SubFactory(CourseFactory)
owner = factory.SubFactory(UserFactory)
72 changes: 72 additions & 0 deletions src/backend/joanie/core/migrations/0002_coursewish.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Generated by Django 4.0.10 on 2023-02-23 06:39

import uuid

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("core", "0001_initial"),
]

operations = [
migrations.CreateModel(
name="CourseWish",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="primary key for the record as UUID",
primary_key=True,
serialize=False,
verbose_name="id",
),
),
(
"created_on",
models.DateTimeField(
auto_now_add=True,
help_text="date and time at which a record was created",
verbose_name="created on",
),
),
(
"updated_on",
models.DateTimeField(
auto_now=True,
help_text="date and time at which a record was last updated",
verbose_name="updated on",
),
),
(
"course",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="wished_in_wishlists",
to="core.course",
verbose_name="Course",
),
),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="wishlists",
to=settings.AUTH_USER_MODEL,
verbose_name="Owner",
),
),
],
options={
"verbose_name": "Course Wish",
"verbose_name_plural": "Course Wishes",
"db_table": "joanie_course_wish",
"unique_together": {("owner", "course")},
},
),
]
1 change: 1 addition & 0 deletions src/backend/joanie/core/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from .certifications import *
from .courses import *
from .products import *
from .wishlist import *
37 changes: 37 additions & 0 deletions src/backend/joanie/core/models/wishlist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
Declare and configure the models for the wishlist part
"""
from django.db import models
from django.utils.translation import gettext_lazy as _

from . import Course, User
from .base import BaseModel


class CourseWish(BaseModel):
"""
CourseWish represents and records a user wish to participate at a course
"""

owner = models.ForeignKey(
to=User,
verbose_name=_("Owner"),
related_name="wishlists",
on_delete=models.PROTECT,
)

course = models.ForeignKey(
to=Course,
verbose_name=_("Course"),
related_name="wished_in_wishlists",
on_delete=models.PROTECT,
)

class Meta:
db_table = "joanie_course_wish"
verbose_name = _("Course Wish")
verbose_name_plural = _("Course Wishes")
unique_together = ("owner", "course")

def __str__(self):
return f"{self.owner}'s wish to participate at the course {self.course}"
17 changes: 17 additions & 0 deletions src/backend/joanie/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from joanie.core import models, utils

from .enums import ORDER_STATE_PENDING, ORDER_STATE_VALIDATED
from .models import Course


class CertificationDefinitionSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -545,3 +546,19 @@ class Meta:
model = models.Certificate
fields = ["id"]
read_only_fields = ["id"]


class CourseWishSerializer(serializers.ModelSerializer):
"""
CourseWish model serializer
"""

id = serializers.CharField(read_only=True, required=False)
course = serializers.SlugRelatedField(
slug_field="code", queryset=Course.objects.all()
)

class Meta:
model = models.CourseWish
fields = ["id", "course"]
read_only_fields = ["id"]
Loading

0 comments on commit 1aa2177

Please sign in to comment.