mirror of
https://github.com/jazzband/django-avatar.git
synced 2026-03-16 22:20:30 +00:00
* Add Avatar API support * extend rest_framework to INSTALLED_APPS * add api path to urls * add requirements.txt to api app * add self describe to assign_width_or_height function * add django-avatar api docs * remove unused files * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Johannes Wilm <mail@johanneswilm.org>
134 lines
5.3 KiB
Python
134 lines
5.3 KiB
Python
from django.db.models import QuerySet
|
|
from django.utils.translation import gettext_lazy as _
|
|
from rest_framework import permissions, status, viewsets
|
|
from rest_framework.decorators import action
|
|
from rest_framework.exceptions import ValidationError
|
|
from rest_framework.response import Response
|
|
|
|
from avatar.api.serializers import AvatarSerializer
|
|
from avatar.api.utils import HTMLTagParser, assign_width_or_height, set_new_primary
|
|
from avatar.models import Avatar
|
|
from avatar.templatetags.avatar_tags import avatar
|
|
from avatar.utils import get_default_avatar_url, get_primary_avatar, invalidate_cache
|
|
|
|
|
|
class AvatarViewSets(viewsets.ModelViewSet):
|
|
serializer_class = AvatarSerializer
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
queryset = Avatar.objects.select_related("user").order_by(
|
|
"-primary", "-date_uploaded"
|
|
)
|
|
|
|
@property
|
|
def parse_html_to_json(self):
|
|
default_avatar = avatar(self.request.user)
|
|
html_parser = HTMLTagParser()
|
|
html_parser.feed(default_avatar)
|
|
return html_parser.output
|
|
|
|
def get_queryset(self):
|
|
assert self.queryset is not None, (
|
|
"'%s' should either include a `queryset` attribute, "
|
|
"or override the `get_queryset()` method." % self.__class__.__name__
|
|
)
|
|
|
|
queryset = self.queryset
|
|
if isinstance(queryset, QuerySet):
|
|
# Ensure queryset is re-evaluated on each request.
|
|
queryset = queryset.filter(user=self.request.user)
|
|
return queryset
|
|
|
|
def list(self, request, *args, **kwargs):
|
|
queryset = self.filter_queryset(self.get_queryset())
|
|
if queryset:
|
|
page = self.paginate_queryset(queryset)
|
|
if page is not None:
|
|
serializer = self.get_serializer(page, many=True)
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
serializer = self.get_serializer(queryset, many=True)
|
|
data = serializer.data
|
|
return Response(data)
|
|
|
|
return Response(
|
|
{
|
|
"message": "You haven't uploaded an avatar yet. Please upload one now.",
|
|
"default_avatar": self.parse_html_to_json,
|
|
}
|
|
)
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
self.perform_create(serializer)
|
|
headers = self.get_success_headers(serializer.data)
|
|
message = _("Successfully uploaded a new avatar.")
|
|
|
|
context_data = {"message": message, "data": serializer.data}
|
|
return Response(context_data, status=status.HTTP_201_CREATED, headers=headers)
|
|
|
|
def destroy(self, request, *args, **kwargs):
|
|
instance = self.get_object()
|
|
if instance.primary is True:
|
|
# Find the next avatar, and set it as the new primary
|
|
set_new_primary(self.get_queryset(), instance)
|
|
self.perform_destroy(instance)
|
|
message = _("Successfully deleted the requested avatars.")
|
|
return Response(message, status=status.HTTP_204_NO_CONTENT)
|
|
|
|
def update(self, request, *args, **kwargs):
|
|
partial = kwargs.pop("partial", False)
|
|
instance = self.get_object()
|
|
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
|
serializer.is_valid(raise_exception=True)
|
|
avatar_image = serializer.validated_data.get("avatar")
|
|
primary_avatar = serializer.validated_data.get("primary")
|
|
if not primary_avatar and avatar_image:
|
|
raise ValidationError("You cant update an avatar image that is not primary")
|
|
|
|
if instance.primary is True:
|
|
# Find the next avatar, and set it as the new primary
|
|
set_new_primary(self.get_queryset(), instance)
|
|
|
|
self.perform_update(serializer)
|
|
invalidate_cache(request.user)
|
|
message = _("Successfully updated your avatar.")
|
|
if getattr(instance, "_prefetched_objects_cache", None):
|
|
# If 'prefetch_related' has been applied to a queryset, we need to
|
|
# forcibly invalidate the prefetch cache on the instance.
|
|
instance._prefetched_objects_cache = {}
|
|
context_data = {"message": message, "data": serializer.data}
|
|
return Response(context_data)
|
|
|
|
@action(
|
|
["GET"], detail=False, url_path="render_primary", name="Render Primary Avatar"
|
|
)
|
|
def render_primary(self, request, *args, **kwargs):
|
|
"""
|
|
|
|
URL Example :
|
|
|
|
1 - render_primary/
|
|
2 - render_primary/?width=400 or render_primary/?height=400
|
|
3 - render_primary/?width=500&height=400
|
|
"""
|
|
context_data = {}
|
|
avatar_size = assign_width_or_height(request.query_params)
|
|
|
|
width = avatar_size.get("width")
|
|
height = avatar_size.get("height")
|
|
|
|
primary_avatar = get_primary_avatar(request.user, width=width, height=height)
|
|
|
|
if primary_avatar and primary_avatar.primary:
|
|
url = primary_avatar.avatar_url(width, height)
|
|
|
|
else:
|
|
url = get_default_avatar_url()
|
|
if bool(request.query_params):
|
|
context_data.update(
|
|
{"message": "Resize parameters not working for default avatar"}
|
|
)
|
|
|
|
context_data.update({"image_url": request.build_absolute_uri(url)})
|
|
return Response(context_data)
|