Saltar a contenido

Code Documentation

This section provides a detailed technical reference for the backend data models. All models inherit from our base utility classes to ensure data consistency.

API Manual

This page contains all necesary documentation about API endpoints: API Documentation

Architecture Overview

The following diagram illustrates the relationship between our base models and the domain-specific entities.

---
config:
  layout: elk
---
graph TD
    Root[MoviesXMoviesBackend] --> Shared[shared/]
    Root --> Persons[persons/]
    Root --> Users[users/]
    Root --> Platforms[platforms/]
    Root --> Genres[genres/]
    Root --> Awards[awards/]
    Root --> Movies[movies/]
    Root --> MovieLists[movielists/]
    Root --> Ratings[ratings/]
    Root --> Reviews[reviews/]

    subgraph Module: Persons
    Persons --> P_Models[models.py]
    Persons --> P_Views[views.py]
    Persons --> P_Urls[urls.py]
    end

    subgraph Module: Platforms
    Platforms --> PL_Models[models.py]
    Platforms --> PL_Views[views.py]
    Platforms --> PL_Urls[urls.py]
    end

    subgraph Module: Awards
    Awards --> A_Models[models.py]
    Awards --> A_Views[views.py]
    Awards --> A_Urls[urls.py]
    end

    subgraph Module: Genres
    Genres --> G_Models[models.py]
    Genres --> G_Views[views.py]
    Genres --> G_Urls[urls.py]
    end

    subgraph Module: Shared
    Shared --> S_Models[models.py]
    Shared --> S_Decorators[decorators.py]
    Shared --> S_Middleware[middleware.py]
    Shared --> S_Signals[signals.py]
    Shared --> S_Utils[utils.py]
    Shared --> S_Handlers[handlers.py]
    end

    subgraph Module: Ratings
    Ratings --> R_Models[models.py]
    end

    subgraph Module: Reviews
    Reviews --> RV_Models[models.py]
    Reviews --> RV_Views[views.py]
    Reviews --> RV_Urls[urls.py]
    end

Main

Urls

Shared

Common utility classes and Mixins used across all application modules.

Models

shared.models.BaseModel

Bases: Model

An abstract base class model that provides self-updating 'created_at' and 'updated_at' fields to any model that inherits from it. Also includes a 'deleted_at' field for soft deletion.

Attributes:

Name Type Description
created_at DateTimeField

The date and time when the record was created.

updated_at DateTimeField

The date and time when the record was last updated.

deleted_at DateTimeField

The date and time when the record was soft deleted.

Note

This is an abstract model and will not create a database table.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

shared.models.SoftDeleteQuerySet

Bases: QuerySet

A custom QuerySet that implements soft deletion by filtering out objects with a non-null 'deleted_at' field.

Views

shared.views.GoogleLogin

Bases: SocialLoginView

View for handling Google social login using the allauth library. This view uses the GoogleOAuth2Adapter to manage the OAuth2 flow and the OAuth2Client to handle the client-side interactions. The callback URL is dynamically generated based on the request's security and host information, allowing for flexibility in different deployment environments.

shared.views.CustomTokenObtainPairView

Bases: TokenObtainPairView

View for obtaining JWT token pairs (access and refresh tokens) using a custom serializer. This view extends the default TokenObtainPairView provided by the Simple JWT library, allowing for customization of the token generation process through the CustomTokenObtainPairSerializer.

Serializer

shared.serializers.CustomTokenObtainPairSerializer

Bases: TokenObtainPairSerializer

Custom serializer for obtaining JWT token pairs (access and refresh tokens) that includes additional user information in the token payload. This serializer extends the default TokenObtainPairSerializer provided by the Simple JWT library, allowing for customization of the token generation process to include fields such as username, boarded status, verified status, and preferred language of the user.

shared.serializers.BaseSerializer

Bases: ABC

Base serializer class that provides a structure for serializing objects or iterables of objects into JSON format. This class includes methods for building absolute URLs, serializing individual instances, and generating JSON responses. It also provides class methods for defining the schema of the serialized data, which can be used for documentation purposes with tools like drf-spectacular.

Decorators

shared.decorators.require_http_methods(methods)

Decorator factory that restricts a view to specific HTTP methods.

Parameters:

Name Type Description Default
methods list[str]

A list of allowed HTTP method strings (e.g., ['GET', 'POST']).

required

Returns:

Name Type Description
Callable

A decorator that wraps a view function and enforces

the allowed HTTP methods.

Example

@require_http_methods(['GET', 'POST']) def my_view(request): ...

shared.decorators.get_query_params(*params_names)

Decorator factory that extracts named query parameters from the request.

Reads each named parameter from request.GET and injects them as keyword arguments into the wrapped view. Missing parameters are passed as None.

Parameters:

Name Type Description Default
*params_names str

Variable number of query parameter names to extract from the URL query string.

()

Returns:

Name Type Description
Callable

A decorator that wraps a view function and injects the

extracted query parameters as keyword arguments.

Example

@get_query_params('page', 'limit') def my_view(request, page=None, limit=None): ...

shared.decorators.get_body(model_class, required_fields)

Decorator factory that parses and validates the JSON request body.

Deserializes the request body as JSON, validates that all required_fields are present, and either instantiates a model_class object or passes the raw dict to the view.

Parameters:

Name Type Description Default
model_class type | None

A class to instantiate with the extracted fields as keyword arguments. If None, the cleaned data dict is passed directly under the body keyword argument.

required
required_fields list[str]

A list of field names that must be present in the JSON body. Returns 400 if any are missing.

required

Returns:

Name Type Description
Callable

A decorator that wraps a view function and injects the

parsed body (or model instance) as a keyword argument.

Raises:

Type Description
JsonResponse(400)

If the request body is not valid JSON.

JsonResponse(400)

If any field in required_fields is absent from the parsed body.

Example

@get_body(UserModel, ['username', 'email']) def my_view(request, usermodel=None): ...

@get_body(None, ['username', 'email']) def my_view(request, body=None): ...

shared.decorators.cached_view(make_key, timeout=300)

Cache a view's JSON response. make_key: callable(request, args, *kwargs) -> str

Middleware

shared.middleware.RequestLogMiddleware

Signals

shared.signals.invalidate_reaction_caches(sender, instance, **kwargs)

shared.signals.invalidate_actor_movies_on_change(sender, instance, action, pk_set, **kwargs)

shared.signals.invalidate_director_movies_on_change(sender, instance, action, pk_set, **kwargs)

shared.signals.invalidate_movie_genres_on_change(sender, instance, action, pk_set, **kwargs)

shared.signals.invalidate_movie_platforms_on_change(sender, instance, action, pk_set, **kwargs)

shared.signals.invalidate_movie_awards_on_change(sender, instance, action, pk_set, **kwargs)

shared.signals.invalidate_movie_detail(sender, instance, **kwargs)

shared.signals.invalidate_on_rating(sender, instance, **kwargs)

shared.signals.invalidate_on_review(sender, instance, **kwargs)

shared.signals.invalidate_user_detail(sender, instance, **kwargs)

shared.signals.invalidate_on_movielist(sender, instance, **kwargs)

shared.signals.invalidate_on_movielist_movies_change(sender, instance, **kwargs)

shared.signals.invalidate_on_comment(sender, instance, created, **kwargs)

shared.signals.invalidate_on_friendship(sender, instance, **kwargs)

shared.signals.invalidate_on_friend_request(sender, instance, **kwargs)

shared.signals.invalidate_on_award(sender, instance, created, **kwargs)

shared.signals.invalidate_person_awards_on_change(sender, instance, action, pk_set, **kwargs)

shared.signals.invalidate_on_person(sender, instance, created, **kwargs)

shared.signals.invalidate_on_genre(sender, instance, created, **kwargs)

shared.signals.invalidate_on_platform(sender, instance, created, **kwargs)

Utils

shared.utils.get_object_or_json_404(klass, *args, **kwargs)

Retrieves a single object from the database based on the provided model class and lookup parameters. If the object does not exist, it raises an Http404 exception with a custom error message.

Parameters:

Name Type Description Default
klass Model or QuerySet

The model class or queryset to query.

required
*args

Positional arguments to pass to the queryset's get() method.

()
**kwargs

Keyword arguments to pass to the queryset's get() method.

{}

Returns:

Type Description

Model instance: The retrieved object if it exists.

shared.utils.get_paginated_response(queryset, serializer_class, request, page, limit)

Creates a paginated response

Parameters:

Name Type Description Default
queryset queryset

Queryset to execute and paginate

required
serializer_class

Class to serialize the objects in the queryset

required
request request

Request object containing user context

required
page number

Page number to retrieve

required
limit number

Number of items per page

required

Returns:

Type Description

django.http.JsonResponse: JsonResponse with paginated results and metadata

shared.utils.get_progressive_response(queryset, serializer_class, request, last_id=None, limit=10, ordering_field='-pk', order=True)

shared.utils.activate_request_language(request)

shared.utils.deactivate_language(previous_language)

shared.utils.translate_text(text, target_lang='en')

Handlers

shared.handlers.custom_handler404(request, exception)


Persons

Management of industry professionals, including actors, actresses, and directors.

Models

persons.models.Person

Bases: BaseModel

Model representing a celebrity, usually an actor/actress or director.

Attributes:

Name Type Description
name CharField

The full name of the person.

slug SlugField

A URL-friendly version of the person's name.

image ImageField

A profile image of the person.

country CharField

The country of origin of the person.

PersonTranslation

Bases: BaseModel

Model representing a translation of a person's name and biography.

Attributes:

Name Type Description
person ForeignKey

The person this translation belongs to.

language CharField

The language code of the translation.

biography TextField

The translated biography of the person.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

Views

persons.views.person_detail(request, person)

persons.views.actors_pagination(request, page=1, limit=10, name=None)

persons.views.directors_pagination(request, page=1, limit=10, name=None)

persons.views.person_acted_movies(request, person, last_id=None, limit=10)

persons.views.person_directed_movies(request, person, last_id=None, limit=10)


Platforms

Streaming services and distribution channels documentation.

Models

platforms.models.Platform

Bases: BaseModel

Model representing a streaming platform.

Attributes:

Name Type Description
name CharField

The name of the platform.

slug SlugField

A URL-friendly version of the platform's name.

url URLField

The official website URL of the platform.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.


Awards

Industry recognitions, festivals, and cinematic awards.

Models

awards.models.Award

Bases: BaseModel

An award or nomination given in recognition of excellence in cinematic achievements.

Attributes:

Name Type Description
name CharField

The name of the award.

slug CharField

A URL-friendly version of the award's name.

category CharField

The category of the award.

icon ImageField

An icon representing the award.

date DateField

The date when the award was given.

Category

Bases: TextChoices

Enumeration of award categories.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.


Genres

Film categories and genre classifications.

Models

genres.models.Genre

Bases: BaseModel

A movie genre model

Attributes:

Name Type Description
name CharField

The name of the genre.

slug SlugField

A URL-friendly version of the genre's name.

GenreTranslation

Bases: BaseModel

A model representing the translation of a genre's name.

Attributes:

Name Type Description
genre ForeignKey

A foreign key to the Genre model.

language CharField

The language code for the translation.

name CharField

The translated name of the genre.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.


Users

Core user management, authentication, and profile data.

Models

users.models.User

Bases: AbstractUser

Custom user model extending Django's AbstractUser.

Attributes:

Name Type Description
bio TextField

A brief biography of the user.

boarded BooleanField

Indicates if the user has completed onboarding.

verified BooleanField

Indicates if the user's email is verified.

email EmailField

The user's email address, must be unique.

picture ImageField

The user's profile picture, with a default image.

following_person ManyToManyField

A many-to-many relationship to Person model for following people.

platforms ManyToManyField

A many-to-many relationship to Platform model for platforms the user is associated with.

verification_code CharField

A code used for email verification, can be null or blank.

is_friend(check_user)

Checks if users are friends (mutual following)

Parameters:

Name Type Description Default
check_user User

The user to check with

required

Returns:

Name Type Description
Boolean

If they are friends or not

remove_friend(friend_user)

Remove a friend relationship between self and friend_user.

suggest_friends()

Suggest friends based on mutual friends, with a recency fallback.

Strategy

Everything runs as a single SQL round-trip using correlated subqueries — no Python-side list materialisation.

  1. already_friend — Exists() subquery: candidate is already a friend.
  2. active_request — Exists() subquery: non-rejected FriendRequest exists.
  3. common_friends_count — correlated COUNT: how many users are friends of both self and the candidate row, computed entirely in SQL.

Ordering: mutual-friends desc → date_joined desc → id asc. This naturally degrades to a recency sort when common_friends_count = 0 for everyone (new user, isolated graph), so no separate fallback branch or extra query is needed.

Parameters:

Name Type Description Default
limit int

Maximum number of suggestions to return. Defaults to 10.

required

Returns:

Type Description

QuerySet[User]: Annotated with common_friends_count.

users.models.FriendRequest

Bases: Model

Model representing a friend request between users.

Attributes:

Name Type Description
from_user ForeignKey

The user who sent the friend request.

to_user ForeignKey

The user who received the friend request.

created_at DateTimeField

The timestamp when the friend request was created.

accept()

Accept the friend request, creating a FriendShip record.

reject()

Reject the friend request.

reset()

Reset a rejected/accepted friend request back to pending.

users.models.FriendShip

Bases: Model

Model representing a friendship between two users.

Attributes:

Name Type Description
user1 ForeignKey

One user in the friendship.

user2 ForeignKey

The other user in the friendship.

created_at DateTimeField

The timestamp when the friendship was created.

Decorators

users.decorators.auth_required(require_verification=True)

Decorator that enforces JWT authentication on a view.

Extracts the Bearer token from the Authorization header, decodes and validates it, resolves the corresponding User, and attaches it to request.user before delegating to the wrapped view.

Unverified users are only permitted to access verify_user and resend_verification_email endpoints.

Parameters:

Name Type Description Default
func Callable

The view function to protect.

required

Returns:

Name Type Description
Callable

The wrapped view function that performs authentication

before calling the original view.

Signals

users.signals.send_verification_email_on_created(sender, instance, created, **kwargs)

Tasks

users.tasks.send_verification_email(user)

Generate a verification code and send it to the user via email.

users.tasks.send_password_reset_email(user)

Generate a password reset code and send it to the user via email.

Views

users.views.VerifyUserSerializer

Bases: Serializer

Serializer for validating account verification payloads.

Attributes:

Name Type Description
verification_code CharField

The verification code sent to the user via email.

users.views.FriendResponse

Bases: Serializer

Serializer for the friend request response payload.

Attributes:

Name Type Description
is_friend BooleanField

Whether the authenticated user is currently friends with the target user.

users.views.SignupUserSerializer

Bases: Serializer

Serializer for validating user signup payloads.

Attributes:

Name Type Description
email EmailField

User email address.

username CharField

Desired username.

first_name CharField

User first name.

last_name CharField

User last name.

password CharField

Desired password.

users.views.UserUpdateSerializer

Bases: Serializer

Serializer for validating user profile update payloads.

All fields are optional; only provided fields are updated.

Attributes:

Name Type Description
email EmailField

Updated email address.

username CharField

Updated username.

first_name CharField

Updated first name.

last_name CharField

Updated last name.

password CharField

Updated password.

picture ImageField

Updated profile picture.

bio CharField

Updated user bio.

users.views.ForgotPasswordResponse

Bases: Serializer

Serializer for the forgot password initiation response.

Attributes:

Name Type Description
status BooleanField

Whether the reset email was sent.

users.views.ForgotPasswordValidationSerializer

Bases: Serializer

Serializer for validating forgot password confirmation payloads.

Attributes:

Name Type Description
forgot_password_code CharField

The reset code sent to the user via email.

new_password CharField

The desired new password.

email EmailField

The user's email address.

users.views.ChangePreferredLanguageSerializer

Bases: Serializer

Serializer for validating preferred language change payloads.

Attributes:

Name Type Description
preferred_language ChoiceField

A language code from settings.SUPPORTED_LANGUAGES.

users.views.ChangePreferredLanguageResponse

Bases: Serializer

Serializer for the preferred language change response.

Attributes:

Name Type Description
status BooleanField

Whether the language was updated.

users.views.GetPreferredLanguageResponse

Bases: Serializer

Serializer for the get preferred language response.

Attributes:

Name Type Description
preferred_language CharField

The user's current preferred language code.

users.views.UserTranslationSerializer

Bases: Serializer

users.views.OnboardingResponse

Bases: Serializer

Serializer for the onboarding response.

Attributes:

Name Type Description
status BooleanField

Whether the onboarding was completed.

users.views.verify_user(request, body)

Verify the authenticated user's account using a code sent via email.

If the user is already verified, returns success immediately. Otherwise compares the submitted code against the stored verification code.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
body dict

Parsed request body containing 'verification_code', injected by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': True} with HTTP 200 on success, or a

JsonResponse

JSON error body with HTTP 400 if the code is incorrect.

users.views.resend_verification_email(request)

Resend the verification email to the authenticated user.

Enforces a 60-second cooldown per user using the Django cache. If the user is already verified, returns success without sending an email.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': 'User is already verified'} if already

JsonResponse

verified, a JSON error body with HTTP 429 if the cooldown is active,

JsonResponse

or {'status': 'Verification email resent'} with HTTP 200 on success.

users.views.suggested_users(request, last_id, limit)

Return a paginated list of suggested users for the authenticated user to follow.

Suggestions are generated by request.user.suggest_friends().

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
last_id int

The last ID for progressive pagination, injected by get_query_params.

required
limit int

Number of items per page, injected by get_query_params.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Paginated serialized user list with HTTP 200.

users.views.self_user_wrapper(request)

Route GET and PUT requests for the authenticated user's own profile.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from self_user_detail on GET,

JsonResponse

or from update_user on PUT.

users.views.self_user_detail(request)

Return the serialized profile of the authenticated user.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized user data with HTTP 200.

users.views.update_user(request, user)

Apply partial updates to a user profile and persist the changes.

Updates only the fields present in request.data that differ from the current values. Handles password hashing, email verification reset, and model-level validation via full_clean().

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request. request.data may contain any subset of fields defined in UserUpdateSerializer.

required
user User

The user instance to update.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized updated user with HTTP 200, or a JSON error

JsonResponse

body with HTTP 400 on validation failure.

users.views.forgot_password_wrapper(request)

Route GET and POST forgot-password requests to their respective handlers.

Parameters:

Name Type Description Default
request

The incoming HTTP request. No authentication required.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from forgot_password on GET,

JsonResponse

or from forgot_password_validation on POST.

users.views.forgot_password(request, email)

Initiate the password reset flow by sending a reset email.

Looks up the user by email and dispatches a password reset email asynchronously via Celery.

Parameters:

Name Type Description Default
request

The incoming HTTP request.

required
email str

The email address to look up, injected by get_query_params.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': 'Password reset email sent'} with HTTP 200,

JsonResponse

or a JSON error body with HTTP 404 if no user matches the email.

users.views.forgot_password_validation(request, body)

Validate a password reset code and apply the new password.

Looks up the user by email, verifies the reset code, validates the new password via Django's password validators, and persists the change.

Parameters:

Name Type Description Default
request

The incoming HTTP request.

required
body dict

Parsed request body containing 'forgot_password_code', 'new_password', and 'email', injected by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': 'Password reset successful'} with HTTP 200,

JsonResponse

or a JSON error body with HTTP 400 on invalid code or validation failure,

JsonResponse

or HTTP 400 if the user is not found.

users.views.user_detail(request, user)

Return the serialized profile of a specific user.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized user data with HTTP 200.

users.views.user_signup(request)

Create and persist a new user account.

Runs model-level validation via full_clean(), validates the password via Django's password validators, hashes it, and saves the new user.

Parameters:

Name Type Description Default
request

The incoming HTTP request.

required
user User

Unsaved User instance constructed from the request body by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized new user with HTTP 200, or a JSON error

JsonResponse

body with HTTP 400 on validation failure.

users.views.preferred_language_wrapper(request)

Route GET and POST requests for the authenticated user's preferred language.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns: JsonResponse: The response from get_preferred_language on GET, or from set_preferred_language on POST.

users.views.get_preferred_language(request)

Return the authenticated user's preferred language.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'preferred_language': str} with HTTP 200.

users.views.set_preferred_language(request, body)

Set the preferred language for the authenticated user.

Validates the submitted language code against settings.SUPPORTED_LANGUAGES before persisting the change.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
body dict

Parsed request body containing 'preferred_language', injected by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': True} with HTTP 200, or a JSON error

JsonResponse

body with HTTP 400 if the language code is not supported.

users.views.complete_onboarding(request)

Mark the authenticated user's onboarding as complete.

Sets the boarded field to True for the requesting user.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': True} with HTTP 200.

users.views.user_reviews(request, user, last_id=None, limit=10)

Return a paginated list of reviews written by a specific user.

Reviews are ordered by most recently created first.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user instance resolved from the URL.

required
last_id int

The last ID for progressive pagination. Defaults to None.

None
limit int

Number of items per page. Defaults to 10.

10

Returns:

Name Type Description
JsonResponse JsonResponse

Paginated serialized reviews with HTTP 200.

users.views.user_friends(request, user, last_id=None, limit=10)

Return a paginated list of a specific user's friends.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user instance resolved from the URL.

required
last_id int

The last ID for progressive pagination. Defaults to None.

None
limit int

Number of items per page. Defaults to 10.

10

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized list of friends with HTTP 200.

users.views.self_friend_wrapper(request)

users.views.delete_friend(request, username)

Delete the friend relationship between the authenticated user and the specified user.

If they are friends, deletes the friendship. If there is no relationship, does nothing.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The target user instance resolved from the URL.

required

Returns: JsonResponse: A JSON response with a 'status' message indicating the result of the operation

users.views.self_friends(request, last_id=None, limit=10)

Return a paginated list of the authenticated user's friends.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
last_id int

The last ID for progressive pagination. Defaults to None.

None
limit int

Number of items per page. Defaults to 10.

10

Returns:

Name Type Description
JsonResponse JsonResponse

Paginated serialized friends with HTTP 200.

users.views.self_friend_requests(request, last_id=None, limit=10)

Return a paginated list of incoming friend requests for a specific user.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user instance resolved from the URL.

required
last_id int

The last ID for progressive pagination. Defaults to None.

None
limit int

Number of items per page. Defaults to 10.

10

Returns: JsonResponse: Paginated serialized friend requests with HTTP 200.

users.views.friend_requests_wrapper(request, user)

users.views.save_accept_friend_request(request, user)

Create a new friend request or accept an incoming request between the authenticated user and the specified user. - If they are already friends, returns an error. - If there is a pending friend request from the authenticated user to the specified user, returns an error. - If there is a pending friend request from the specified user to the authenticated user, accepts it and establishes the friendship. - If there is no existing relationship, creates a new pending friend request from the authenticated user to the specified user. Args: request: The authenticated incoming HTTP request. user (User): The target user instance resolved from the URL. Returns: JsonResponse: A JSON response with a 'status' message indicating the result of the operation

users.views.delete_friend_request(request, user)

Delete the friend relationship or pending friend request between the authenticated user and the specified user.

If they are friends, deletes the friendship. If there is a pending friend request in either direction, deletes it. If there is no relationship, does nothing.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The target user instance resolved from the URL.

required

Returns: JsonResponse: {'status': 'Unfriended'} with HTTP 200 if they were friends, {'status': 'Friend request deleted'} if a pending request was deleted, or a JSON error body with HTTP 400 if the user tries to unfriend themselves.

Search for users by username or name.

Accepts a 'search_query' parameter and returns a list of users whose username, first name, or last name contains the query string (case-insensitive).

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request with a 'search_query' GET parameter.

required

Returns: JsonResponse: A JSON response containing a list of matching users serialized with UserSerializer.

users.views.user_translations_deepl(request, user)


Movies

The base of the application, movies connected with almost everything

Models

movies.models.Movie

Bases: BaseModel

A model representing a movie with its details.

Attributes:

Name Type Description
title CharField

The title of the movie.

slug SlugField

A URL-friendly version of the movie's title.

synopsis TextField

A brief summary of the movie's plot.

release_date DateField

The date when the movie was released.

cover ImageField

An image representing the movie's cover.

directors ManyToManyField

A many-to-many relationship to the Person model for directors.

actors ManyToManyField

A many-to-many relationship to the Person model for actors.

genres ManyToManyField

A many-to-many relationship to the Genre model.

platforms ManyToManyField

A many-to-many relationship to the Platform model

MovieTranslation

Bases: BaseModel

A model representing the translation of a movie's title and synopsis.

Attributes:

Name Type Description
movie ForeignKey

A foreign key to the Movie model.

language CharField

The language code for the translation.

title CharField

The translated title of the movie.

synopsis TextField

The translated synopsis of the movie.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

Tasks

movies.tasks.retrain_professional_model()

Retrain the ALS recommendation model and store it in the cache.

Fetches all user-item ratings from the database, builds a sparse item-user interaction matrix, trains an ALS model via the Implicit library, and serializes the resulting model and ID mappings into the Django cache under the key 'movie_recommendation_model'.

The cached payload is a pickle-serialized dict with the keys:

  • model: the fitted AlternatingLeastSquares instance.
  • user_id_map: mapping from original user PKs to contiguous indices.
  • movie_id_map: mapping from original movie PKs to contiguous indices.
  • reverse_movie_map: inverse of movie_id_map.
  • user_items_matrix: transposed user-item csr_matrix.

Returns:

Name Type Description
str str

'No ratings to train the model' if no ratings exist,

str

otherwise 'Model Implicit (ALS) trained'.

Views

movies.views.ReviewSaveSerializer

Bases: Serializer

Serializer for validating review creation payloads.

Attributes:

Name Type Description
is_positive BooleanField

Whether the review is positive.

title CharField

Title of the review.

content CharField

Body content of the review.

movies.views.RatingSaveSerializer

Bases: Serializer

Serializer for validating rating creation and update payloads.

Attributes:

Name Type Description
rating IntegerField

Numeric rating value between 1 and 5.

movies.views.MoviesInListSerializer

Bases: ModelSerializer

Serializer for representing a Movie inside a movie list.

Exposes a subset of movie fields suitable for list and recommendation display contexts.

movies.views.movie_detail(request, movie)

Return the full detail representation of a single movie.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized movie data with HTTP 200.

movies.views.movie_friends_ratings(request, movie, page=1, limit=10)

Return a paginated list of friend ratings for a specific movie.

Only ratings from users in request.user.friends are included, ordered by most recently created first.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required
page int

Page number for pagination. Defaults to 1.

1
limit int

Number of items per page. Defaults to 10.

10

Returns:

Name Type Description
JsonResponse JsonResponse

Paginated serialized ratings with HTTP 200.

movies.views.movie_review_wrapper(request, movie)

Route GET and POST review requests to their respective handlers.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from movie_reviews on GET,

JsonResponse

or from save_movie_review on POST.

movies.views.movie_reviews(request, movie, limit=10, last_id=None)

movies.views.save_movie_review(request, movie, review)

Persist a new review for a movie and return it serialized.

The review instance is injected by the get_body decorator using the 'is_positive', 'title', and 'content' fields from the request body. user and movie are assigned before saving.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required
review Review

Unsaved Review instance constructed from the request body by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized new review with HTTP 201.

movies.views.movie_rating_wrapper(request, movie)

Route GET, POST, and PUT rating requests to their respective handlers.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from the matched rating handler.

movies.views.get_self_movie_rating(request, movie)

Return the authenticated user's own rating for a specific movie.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized rating with HTTP 200, or a JSON error

JsonResponse

body with HTTP 404 if no rating exists.

movies.views.create_movie_rating(request, movie, rating)

Create and persist the authenticated user's rating for a movie.

Rejects the request if the user has already rated the movie. Runs full_clean() before saving to enforce model-level validation.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required
rating Rating

Unsaved Rating instance constructed from the request body by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized new rating with HTTP 201, or a JSON error

JsonResponse

body with HTTP 400 on duplicate or validation failure.

movies.views.update_movie_rating(request, movie, rating)

Update the authenticated user's existing rating for a movie.

Fetches the persisted rating, applies the new value from the injected rating instance, runs full_clean(), and saves.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movie Movie

The movie instance resolved from the URL.

required
rating Rating

Unsaved Rating instance carrying the new value, constructed by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized updated rating with HTTP 200, a JSON error

JsonResponse

body with HTTP 404 if no prior rating exists, or HTTP 400 on

JsonResponse

validation failure.

movies.views.get_movie_recommendations(request)

Return a ranked list of movie recommendations for the authenticated user.

Pipeline
  1. Build exclusion set (already watched / marked unseen).
  2. Fetch ML candidates from cache, fall back to recency ordering.
  3. Score and sort candidates.
  4. Pad with algorithmic results if the model returns fewer than LIMIT_RECOMMENDATIONS.
  5. Re-query Movie preserving the scored order.
  6. Return serialized response.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized list of up to LIMIT_RECOMMENDATIONS

JsonResponse

recommended movies with HTTP 200.

movies.views._pad_with_algorithmic(existing, exclude_ids, user, needed)

Pad a recommendations list with algorithmically selected fallback movies.

Fills the gap between len(existing) and needed by querying recent movies available on the user's platforms, excluding already seen or existing candidates.

Parameters:

Name Type Description Default
existing list[Movie]

Movies already selected by the scoring pipeline.

required
exclude_ids set[int]

Primary-key set of movies to exclude.

required
user

The authenticated user whose platforms relation is used to filter results.

required
needed int

Total number of recommendations required.

required

Returns:

Type Description
list[Movie]

list[Movie]: The existing list extended with up to

list[Movie]

needed - len(existing) additional Movie instances,

list[Movie]

ordered by -release_date.


Movie List

A list created by an user or administrator, with a privacy setting.

Models

movielists.models.MovieList

Bases: BaseModel

Model representing a list of movies created by a user.

Attributes:

Name Type Description
name CharField

The name of the movie list.

slug SlugField

URL-friendly identifier, unique per user.

description TextField

A brief description of the movie list.

privacity CharField

Visibility setting from Privacity.

user ForeignKey

The user who created the movie list.

movies ManyToManyField

The movies included in the movie list.

Privacity

Bases: TextChoices

Privacy settings controlling who can view a movie list.

Attributes:

Name Type Description
PUBLIC

The movie list is visible to everyone.

FRIENDS

The movie list is visible to the creator's friends.

PRIVATE

The movie list is only visible to the creator.

__str__()

Return the slug as the string representation of the list.

Returns:

Name Type Description
str str

The slug of the movie list.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

intelligent_fill(genres=None, celebrities=None, friends=None)

Populate the movie list using a scored recommendation pipeline.

Excludes already watched or unseen-marked movies, applies hard filters (genre, platform), scores candidates by celebrities, friends' favourites, and awards, then sets the top 40 results on self.movies.

Parameters:

Name Type Description Default
genres list[str] | None

Genre slugs to filter candidates by. Defaults to None.

None
celebrities list[str] | None

Celebrity slugs used to boost movies featuring those actors or directors. Defaults to None.

None
friends list[str] | None

Friend usernames whose highly-rated movies receive a score boost. Defaults to None.

None
restore()

Restore a soft-deleted object by clearing 'deleted_at'.

Views

movielists.views.SaveMovieListSerializer

Bases: Serializer

Serializer for validating movie list creation and update payloads.

Attributes:

Name Type Description
name CharField

Name of the movie list.

description CharField

Description of the movie list.

privacity ChoiceField

Visibility setting from MovieList.Privacity.choices.

movielists.views.movies_list_self_wrapper(request)

Route GET and POST movie list requests to their respective handlers.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from movies_list_self on GET,

JsonResponse

or from save_movie_list_self on POST.

movielists.views.movies_list_self(request, page=1, limit=10)

Return a paginated list of all movie lists owned by the authenticated user.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
page int

Page number for pagination. Defaults to 1.

1
limit int

Number of items per page. Defaults to 10.

10

Returns:

Name Type Description
JsonResponse JsonResponse

Paginated serialized movie lists with HTTP 200.

movielists.views.save_movie_list_self(request, movielist, intelligent)

Create and persist a new movie list for the authenticated user.

Optionally fills the list intelligently using genres, celebrities, and friends query parameters when intelligent is truthy. Validates all parameters before saving.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request. May include genres, celebrities, and friends as multi-value query parameters when intelligent is set.

required
movielist MovieList

Unsaved MovieList instance constructed from the request body by get_body.

required
intelligent str

Query parameter controlling intelligent fill. Treated as False when absent or equal to 'false'.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized new movie list with HTTP 201, or a JSON

JsonResponse

error body with HTTP 400 on validation failure or invalid parameters.

movielists.views._validate_intelligent_params(user, genres, celebrities, friends)

Validate that all provided slugs and usernames exist in the database.

Checks each genre slug against Genre, each celebrity slug against Person, and each friend username against the user's friend list. Returns the first error response encountered, or None if all are valid.

Parameters:

Name Type Description Default
user

The authenticated user whose friends relation is used to validate friend usernames.

required
genres list[str]

List of genre slugs to validate.

required
celebrities list[str]

List of celebrity slugs to validate.

required
friends list[str]

List of friend usernames to validate.

required

Returns:

Name Type Description
JsonResponse JsonResponse | None

A JSON error body with HTTP 400 for the first invalid

JsonResponse | None

value found, or None if all values are valid.

movielists.views.movies_list_list(request, user, last_id=None, limit=10)

Return a paginated list of movie lists belonging to a specific user.

Filters lists by privacity based on the relationship between the authenticated user and the target user. Owners see all lists; friends see public and followers-only lists; others see only public lists.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user whose movie lists are being retrieved, resolved from the URL.

required
last_id int

The last ID for progressive pagination. Defaults to None.

None
limit int

Number of items per page. Defaults to 10.

10

Returns:

Name Type Description
JsonResponse JsonResponse

Paginated serialized movie lists with HTTP 200.

movielists.views.movies_list_detail(request, user, movies_list)

Return the detail of a specific movie list, enforcing privacity rules.

Owners always have access. Public lists are visible to everyone. Followers-only lists are visible only to friends of the owner.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user who owns the movie list, resolved from the URL.

required
movies_list MovieList

The movie list instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized movie list with HTTP 200, or a JSON error

JsonResponse

body with HTTP 404 if the list is private or the requester is not

JsonResponse

allowed to view it.

movielists.views.movies_list_movie_wrapper(request, user, movies_list_slug, movie)

Route POST and DELETE movie-in-list requests to their respective handlers.

Rejects the request if the authenticated user is not the owner of both the list and the user record.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
user User

The user who owns the movie list, resolved from the URL.

required
movies_list_slug str

The slug of the movie list, resolved from the URL.

required
movie Movie

The movie instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from add_movie_to_list on POST, or

JsonResponse

from remove_movie_from_list on DELETE, or a JSON error body

JsonResponse

with HTTP 403 if the requester is not the list owner.

movielists.views.add_movie_to_list(request, movies_list, movie)

Add a movie to a movie list and return the updated list.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movies_list MovieList

The movie list to add the movie to.

required
movie Movie

The movie instance to add.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized updated movie list with HTTP 200.

movielists.views.remove_movie_from_list(request, movies_list, movie)

Remove a movie from a movie list and confirm success.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
movies_list MovieList

The movie list to remove the movie from.

required
movie Movie

The movie instance to remove.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'success': True} with HTTP 200.


Ratings

User ratings for movies, stored on a 1–5 scale.

Models

ratings.models.Rating

Bases: BaseModel

Model representing a rating given by a user to a movie.

Attributes:

Name Type Description
rating PositiveSmallIntegerField

The rating given by the user.

user ForeignKey

The user who gave the rating.

movie ForeignKey

The movie that the rating is about.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.


Reviews

User-written reviews, comments, and emoji reactions on reviews and comments.

Models

reviews.models.Review

Bases: BaseModel

A review of a cinematic work.

Attributes:

Name Type Description
title CharField

The title of the review.

content TextField

The content of the review.

is_positive BooleanField

Indicates if the review is positive or negative.

user ForeignKey

The user who wrote the review.

movie ForeignKey

The movie that the review is about.

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

reviews.models.Comment

Bases: BaseModel

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

reviews.models.Reaction

Bases: BaseModel

delete(**kwargs)

Soft delete the object by setting 'deleted_at' timestamp.

hard_delete(**kwargs)

Permanently delete the object from the database.

restore()

Restore a soft-deleted object by clearing 'deleted_at'.

Views

reviews.views.ReviewUpdateSerializer

Bases: Serializer

Serializer for validating review update payloads.

Attributes:

Name Type Description
is_positive BooleanField

Whether the review is positive.

title CharField

Updated title of the review.

content CharField

Updated body content of the review.

reviews.views.SaveReactionSerializer

Bases: Serializer

reviews.views.SaveCommentSerializer

Bases: Serializer

reviews.views.UpdateCommentSerializer

Bases: Serializer

reviews.views.ReviewDeleteSerializer

Bases: Serializer

Serializer for the review deletion response payload.

Attributes:

Name Type Description
status BooleanField

Whether the deletion was successful.

reviews.views.ReviewTranslationSerializer

Bases: Serializer

reviews.views.CommentTranslationSerializer

Bases: Serializer

reviews.views.review_wrapper(request, review)

Route PUT and DELETE review requests to their respective handlers.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
review Review

The review instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

The response from edit_review on PUT,

JsonResponse

or from delete_review on DELETE.

reviews.views.edit_review(request, review, body)

Update the fields of an existing review.

Only the owner of the review may edit it. Applies 'is_positive', 'title', and 'content' from the request body and persists the changes.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
review Review

The review instance resolved from the URL.

required
body dict

Parsed request body containing 'is_positive', 'title', and 'content', injected by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized updated review with HTTP 200, or a JSON

JsonResponse

error body with HTTP 403 if the requester is not the review owner.

reviews.views.delete_review(request, review)

Delete an existing review.

Only the owner of the review may delete it.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
review Review

The review instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

{'status': True} with HTTP 204 on success, or a

JsonResponse

JSON error body with HTTP 403 if the requester is not the review owner.

reviews.views.get_review(request, review)

Retrieve the details of a review.

Parameters:

Name Type Description Default
request

The incoming HTTP request.

required
review Review

The review instance resolved from the URL.

required

Returns:

Name Type Description
JsonResponse JsonResponse

Serialized review details with HTTP 200, or a JSON

JsonResponse

error body with HTTP 404 if the review does not exist.

reviews.views.reaction_review_wrapper(request, review)

reviews.views.get_review_reactions(request, review)

Retrieve aggregated reaction counts and the requester's reactions for a review.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
review Review

The review instance resolved from the URL.

required

Returns: JsonResponse: A JSON object containing: - 'reactions': A dictionary mapping emoji codes to their total counts. - 'your_reactions': A dictionary mapping emoji codes to the IDs of the requester's reactions.

reviews.views.add_review_reaction(request, review, body)

Add a reaction to a review.

If the requester has already reacted with the same emoji, returns 400. Otherwise, a new reaction is created.

Parameters:

Name Type Description Default
request

The authenticated incoming HTTP request.

required
review Review

The review instance resolved from the URL.

required
body dict

Parsed request body containing 'emoji_code', injected by get_body.

required

Returns:

Name Type Description
JsonResponse JsonResponse

A JSON object containing the status of the operation,

JsonResponse

or an error message if the input is invalid.

reviews.views.comment_wrapper(request, review)

reviews.views.get_review_comments(request, review, limit=10, last_id=None)

reviews.views.add_review_comment(request, review, body)

reviews.views.comment_wrapper_with_id(request, review, comment)

reviews.views.get_comment(request, review, comment)

reviews.views.update_comment(request, review, comment, body)

reviews.views.delete_comment(request, review, comment)

reviews.views.reaction_comment_wrapper(request, review, comment)

reviews.views.get_comment_reactions(request, review, comment)

reviews.views.add_comment_reaction(request, review, comment, body)

reviews.views.reply_wrapper(request, review, comment)

reviews.views.get_comment_replies(request, review, comment, limit=20, last_id=None)

reviews.views.add_comment_reply(request, review, comment, body)

reviews.views.delete_reaction_comment(request, review, comment, reaction)

reviews.views.delete_review_reaction(request, review, reaction)

reviews.views.review_translations_deepl(request, review)

reviews.views.comment_translations_deepl(request, review, comment)