feat: 🙋 improve data returned from user json endpoint

This commit is contained in:
m5ka 2024-03-27 10:26:08 +00:00
parent f5607a4680
commit 83ce6e887e
3 changed files with 64 additions and 50 deletions

View file

@ -4,7 +4,7 @@ from django.contrib import admin
from django.urls import include, path from django.urls import include, path
from moku.views.auth import LoginView, LogoutView from moku.views.auth import LoginView, LogoutView
from moku.views.post import FeedView, LatestPostJSONView from moku.views.post import FeedView
from moku.views.recipe import ( from moku.views.recipe import (
DeleteRecipeView, DeleteRecipeView,
DeleteStepView, DeleteStepView,
@ -14,7 +14,13 @@ from moku.views.recipe import (
ShowRecipeView, ShowRecipeView,
) )
from moku.views.static import ChangelogView, PrivacyView, TermsView from moku.views.static import ChangelogView, PrivacyView, TermsView
from moku.views.user import EditProfileView, EditSettingsView, ProfileView, SignupView from moku.views.user import (
EditProfileView,
EditSettingsView,
ProfileView,
SignupView,
UserJSONView,
)
urlpatterns = [ urlpatterns = [
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
@ -28,7 +34,7 @@ urlpatterns = [
path("privacy", PrivacyView.as_view(), name="privacy"), path("privacy", PrivacyView.as_view(), name="privacy"),
path("terms", TermsView.as_view(), name="terms"), path("terms", TermsView.as_view(), name="terms"),
path("user/<str:username>", ProfileView.as_view(), name="profile"), path("user/<str:username>", ProfileView.as_view(), name="profile"),
path("user/<str:username>/json", LatestPostJSONView.as_view(), name="json"), path("user/<str:username>/json", UserJSONView.as_view(), name="json"),
path("recipes", IndexRecipeView.as_view(), name="recipe.index"), path("recipes", IndexRecipeView.as_view(), name="recipe.index"),
path("recipes/new", NewRecipeView.as_view(), name="recipe.new"), path("recipes/new", NewRecipeView.as_view(), name="recipe.new"),
path("recipes/<str:uuid>", ShowRecipeView.as_view(), name="recipe.show"), path("recipes/<str:uuid>", ShowRecipeView.as_view(), name="recipe.show"),

View file

@ -1,13 +1,7 @@
import json
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import View as BaseView
from moku.constants import EMOJI_CATEGORIES, Verbs from moku.constants import EMOJI_CATEGORIES, Verbs
from moku.forms.post import PostForm from moku.forms.post import PostForm
@ -70,44 +64,3 @@ class FeedView(FormView):
created_by=self.request.user created_by=self.request.user
) )
return form return form
class LatestPostJSONView(BaseView):
"""Renders the latest post from a specific user as JSON."""
def get(self, request, *args, **kwargs):
post = (
Post.objects.prefetch_related("recipe__steps")
.filter(created_by__username=kwargs.get("username"))
.order_by("-created_at")
.first()
)
if not post:
return HttpResponse(
json.dumps({"post": None}), content_type="application/json"
)
post_data = {
"date": {
"iso": str(post.created_at),
"natural": naturaltime(post.created_at),
},
"text": post.get_verb_display()
% {"user": f"@{post.created_by.username}", "food": post.food},
"food": post.food,
"verb": {
"id": post.verb,
"pattern": post.get_verb_display() % {"user": "$1", "food": "$2"},
},
"image": f"{settings.SITE_ROOT_URL}{post.image.url}"
if post.image
else None,
"user": {
"username": post.created_by.username,
"url": f"{settings.SITE_ROOT_URL}{post.created_by.get_absolute_url()}",
},
}
if post.recipe:
post_data["recipe"] = [
step.instructions for step in post.recipe.steps.all()
]
return HttpResponse(json.dumps(post_data), content_type="application/json")

View file

@ -1,13 +1,20 @@
import json
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.db import IntegrityError from django.db import IntegrityError
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy as gettext_lazy from django.utils.translation import gettext_lazy as gettext_lazy
from django.views.generic import View as BaseView
from moku.forms.user import ProfileForm, UserForm, UserSettingsForm from moku.forms.user import ProfileForm, UserForm, UserSettingsForm
from moku.images import process_avatar_image from moku.images import process_avatar_image
from moku.models.post import Post
from moku.models.user import User from moku.models.user import User
from moku.views.base import FormView, View from moku.views.base import FormView, View
@ -103,3 +110,51 @@ class SignupView(FormView):
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
return redirect("feed") return redirect("feed")
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
class UserJSONView(BaseView):
"""
Renders information about a specific user as JSON, including their latest post.
"""
def get(self, request, *args, **kwargs):
user = get_object_or_404(User, username=kwargs.get("username"))
post = (
Post.objects.prefetch_related("recipe__steps")
.filter(created_by=user)
.order_by("-created_at")
.first()
)
if not post:
post_data = None
else:
post_data = {
"date": {
"iso": str(post.created_at),
"natural": naturaltime(post.created_at),
},
"text": post.get_verb_display()
% {"user": f"@{post.created_by.username}", "food": post.food},
"food": post.food,
"verb": {
"id": post.verb,
"pattern": post.get_verb_display() % {"user": "$1", "food": "$2"},
},
"image": f"{settings.SITE_ROOT_URL}{post.image.url}"
if post.image
else None,
"recipe": [step.instructions for step in post.recipe.steps.all()]
if post.recipe
else None,
}
user_data = {
"user": {
"username": user.username,
"avatar": f"{settings.SITE_ROOT_URL}{user.avatar.url}"
if user.avatar
else None,
"url": f"{settings.SITE_ROOT_URL}{user.get_absolute_url()}",
"latest_post": post_data,
}
}
return HttpResponse(json.dumps(user_data), content_type="application/json")