Merge pull request #89 from plers-org/sm/#88

Sm/#88
This commit is contained in:
NKEY
2025-08-21 00:34:10 +09:00
committed by GitHub
4 changed files with 53 additions and 3 deletions

View File

@@ -125,6 +125,7 @@ CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': f'redis://:{REDIS_PASSWORD}@redis:6379/1',
# 'LOCATION': f'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'SERIALIZER': 'django_redis.serializers.json.JSONSerializer',

View File

@@ -3,8 +3,26 @@ from rest_framework.permissions import BasePermission
from projects.models import Project, ProjectTeamList
from portfolios.models import Portfolio
from .services import NocodetoolObjectMapService
UNSAFE_REQUEST = ["POST", "PUT", "PATCH", "DELETE"]
class IsNotPublished(BasePermission):
def has_permission(self, request, view):
if request.method not in UNSAFE_REQUEST:
return True
related_type = request.query_params.get("type")
related_id = request.query_params.get("id")
if not related_type or not related_id:
return False
if obj := NocodetoolObjectMapService.mapping_model_instance(related_type, related_id):
if not obj.is_published:
return True
return False
class IsOwnerOrMemberInCreateAndUpdateAndDelete(BasePermission):
def has_permission(self, request, view):
if request.method not in UNSAFE_REQUEST:

View File

@@ -7,6 +7,11 @@ from portfolios.models import Portfolio
from projects.serializers import ProjectNocodetoolSerializer
from portfolios.serializers import PortfolioNocodetoolSerializer
from django.utils import timezone
from django.db.models import F
from django_redis import get_redis_connection
NOCODETOOL_MODEL_MAP = {
'project': Project,
'portfolio': Portfolio,
@@ -27,3 +32,26 @@ class NocodetoolObjectMapService:
def mapping_model_serializer(related_type: str):
return NOCODETOOL_SERIALIZER_MAP.get(related_type, None)
class NocodetoolHitService:
def hit_once(obj, request, ttl=60*60*24):
user_key = request.user.id if request.user.is_authenticated else request.session.session_key
if not user_key:
request.session.save()
user_key = request.session.session_key()
today = timezone.localdate().isoformat()
key = f"viewed:obj:{obj.id}:{today}"
redis_conn = get_redis_connection("default")
added = redis_conn.sadd(key, user_key)
if added:
if redis_conn.ttl(key) == -1:
redis_conn.expire(key, ttl)
obj.__class__.objects.filter(id=obj.id).update(view_count=F("view_count") + 1)
return True
return False

View File

@@ -7,8 +7,8 @@ from django.db import transaction
from .models import Code, Page, Element
from .serializers import CodeSerializer
from .permissions import IsOwnerOrMemberInCreateAndUpdateAndDelete
from .services import NocodetoolObjectMapService
from .permissions import IsOwnerOrMemberInCreateAndUpdateAndDelete, IsNotPublished
from .services import NocodetoolObjectMapService, NocodetoolHitService
from users.models import User
from portfolios.models import Portfolio
@@ -18,13 +18,16 @@ from bson import ObjectId
class NoCodeToolAPIView(APIView):
permission_classes = [IsAuthenticated, IsOwnerOrMemberInCreateAndUpdateAndDelete]
permission_classes = [IsAuthenticated, IsNotPublished, IsOwnerOrMemberInCreateAndUpdateAndDelete]
@transaction.atomic
def get(self, request):
related_type = request.query_params.get("type")
related_id = request.query_params.get("id")
code_id = None
if obj := NocodetoolObjectMapService.mapping_model_instance(related_type, related_id):
if obj.is_published:
NocodetoolHitService.hit_once(obj, request)
code_id = ObjectId(obj.code_id)
if not code_id: