diff --git a/.gitignore b/.gitignore index 3a68618..d16e659 100644 --- a/.gitignore +++ b/.gitignore @@ -140,4 +140,5 @@ GitHub.sublime-settings # private_key.pem # public_key.pem -db.sqlite3 \ No newline at end of file +db.sqlite3 +poetry.lock \ No newline at end of file diff --git a/apps/blog/api_endpoints/__init__.py b/apps/blog/api_endpoints/__init__.py new file mode 100644 index 0000000..18d8020 --- /dev/null +++ b/apps/blog/api_endpoints/__init__.py @@ -0,0 +1,16 @@ +from rest_framework import routers + +from .blog import ( + PostViewSet, + PostCommentViewSet, + PostCommentLikeViewSet, + PostLikeViewSet, + PostDislikeViewSet +) + +router = routers.DefaultRouter() +router.register("post", PostViewSet, basename="post") +router.register("post_comment", PostCommentViewSet, basename="post-comment") +router.register("post_comment_like", PostCommentLikeViewSet, basename="post-comment-like") +router.register("post_like", PostLikeViewSet, basename="post-like") +router.register("post_dislike", PostDislikeViewSet, basename="post-dislike") diff --git a/apps/blog/api_endpoints/blog/Post/__init__.py b/apps/blog/api_endpoints/blog/Post/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/blog/api_endpoints/blog/Post/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/blog/api_endpoints/blog/Post/serializer.py b/apps/blog/api_endpoints/blog/Post/serializer.py new file mode 100644 index 0000000..084acb3 --- /dev/null +++ b/apps/blog/api_endpoints/blog/Post/serializer.py @@ -0,0 +1,24 @@ +from rest_framework import serializers + +from apps.blog.models import Post + + +class PostSerializer(serializers.ModelSerializer): + class Meta: + model = Post + fields = [ + "id", + "title", + "get_absolute_url", + "status", + "description", + "publisher_at", + "is_active", + "author", + "like_count", + "dislike_count", + "comment_count", + "watching", + "created_at", + "updated_at", + ] \ No newline at end of file diff --git a/apps/blog/api_endpoints/blog/Post/tests.py b/apps/blog/api_endpoints/blog/Post/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/blog/api_endpoints/blog/Post/views.py b/apps/blog/api_endpoints/blog/Post/views.py new file mode 100644 index 0000000..e589730 --- /dev/null +++ b/apps/blog/api_endpoints/blog/Post/views.py @@ -0,0 +1,16 @@ +from rest_framework import viewsets, permissions + +from apps.blog.models import Post +from .serializer import PostSerializer + + +class PostViewSet(viewsets.ModelViewSet): + queryset = Post.published.all().order_by("-created_at") + serializer_class = PostSerializer + + def get_permissions(self): + if self.action in ['list', 'retrieve']: + return [permissions.AllowAny()] + return [permissions.IsAuthenticated()] + +__all__ = ("PostViewSet", ) diff --git a/apps/blog/api_endpoints/blog/PostComment/__init__.py b/apps/blog/api_endpoints/blog/PostComment/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostComment/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/blog/api_endpoints/blog/PostComment/serializers.py b/apps/blog/api_endpoints/blog/PostComment/serializers.py new file mode 100644 index 0000000..a896026 --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostComment/serializers.py @@ -0,0 +1,25 @@ +from rest_framework import serializers + +from apps.blog.models import PostComment, Post +from apps.users.models import User + + +class MiniPostCommentUser(serializers.ModelSerializer): + class Meta: + model = User + fields = ["id", "username", "email", "created_at", "updated_at"] + + +class MiniPostCommentPost(serializers.ModelSerializer): + class Meta: + model = Post + fields = ["id", "title", "created_at", "updated_at"] + + +class PostCommentSerializer(serializers.ModelSerializer): + user = MiniPostCommentUser(read_only=True) + comment = MiniPostCommentPost(read_only=True) + + class Meta: + model = PostComment + fields = ["id", "user", "comment", "created_at", "updated_at"] diff --git a/apps/blog/api_endpoints/blog/PostComment/tests.py b/apps/blog/api_endpoints/blog/PostComment/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/blog/api_endpoints/blog/PostComment/views.py b/apps/blog/api_endpoints/blog/PostComment/views.py new file mode 100644 index 0000000..83ac244 --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostComment/views.py @@ -0,0 +1,16 @@ +from rest_framework import viewsets, permissions + +from apps.blog.models import PostComment +from .serializers import PostCommentSerializer + + +class PostCommentViewSet(viewsets.ModelViewSet): + queryset = PostComment.objects.all().order_by("-created_at") + serializer_class = PostCommentSerializer + + def get_permissions(self): + if self.action in ['list', 'retrieve']: + return [permissions.AllowAny()] + return [permissions.IsAuthenticated()] + +__all__ = ("PostCommentViewSet", ) diff --git a/apps/blog/api_endpoints/blog/PostCommentLike/__init__.py b/apps/blog/api_endpoints/blog/PostCommentLike/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostCommentLike/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/blog/api_endpoints/blog/PostCommentLike/serializers.py b/apps/blog/api_endpoints/blog/PostCommentLike/serializers.py new file mode 100644 index 0000000..623310e --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostCommentLike/serializers.py @@ -0,0 +1,24 @@ +from rest_framework import serializers + +from apps.blog.models import PostCommentLike +from apps.users.models import User + + +class MiniPostCommentLikeUserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ["id", "username", "created_at", "updated_at"] + + +class MiniPostCommentLikePostCommentSerializer(serializers.ModelSerializer): + class Meta: + fields = ["id", "post", "message", "created_at", "updated_at"] + + +class PostCommentLikeSerializer(serializers.ModelSerializer): + user = MiniPostCommentLikeUserSerializer(read_only=True) + comment = MiniPostCommentLikePostCommentSerializer(read_only=True) + + class Meta: + model = PostCommentLike + fields = ["id", "user", "comment"] diff --git a/apps/blog/api_endpoints/blog/PostCommentLike/tests.py b/apps/blog/api_endpoints/blog/PostCommentLike/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/blog/api_endpoints/blog/PostCommentLike/views.py b/apps/blog/api_endpoints/blog/PostCommentLike/views.py new file mode 100644 index 0000000..8c9c3f4 --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostCommentLike/views.py @@ -0,0 +1,12 @@ +from rest_framework import viewsets, permissions + +from apps.blog.models import PostCommentLike +from .serializers import PostCommentLikeSerializer + + +class PostCommentLikeViewSet(viewsets.ModelViewSet): + queryset = PostCommentLike.objects.all().order_by("-id") + serializer_class = PostCommentLikeSerializer + permission_classes = [permissions.IsAuthenticated] + +__all__ = ("PostCommentLikeViewSet", ) diff --git a/apps/blog/api_endpoints/blog/PostDislike/__init__.py b/apps/blog/api_endpoints/blog/PostDislike/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostDislike/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/blog/api_endpoints/blog/PostDislike/serializers.py b/apps/blog/api_endpoints/blog/PostDislike/serializers.py new file mode 100644 index 0000000..270b127 --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostDislike/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from apps.blog.models import PostDislike + + +class PostDislikeSerializer(serializers.ModelSerializer): + class Meta: + model = PostDislike + fields = ["id", "user", "post"] diff --git a/apps/blog/api_endpoints/blog/PostDislike/tests.py b/apps/blog/api_endpoints/blog/PostDislike/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/blog/api_endpoints/blog/PostDislike/views.py b/apps/blog/api_endpoints/blog/PostDislike/views.py new file mode 100644 index 0000000..e17cb1f --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostDislike/views.py @@ -0,0 +1,32 @@ +from django.shortcuts import get_object_or_404 + +from rest_framework import viewsets, response, status, permissions + +from apps.blog.models import PostDislike, PostLike, Post +from .serializers import PostDislikeSerializer + + +class PostDislikeViewSet(viewsets.ModelViewSet): + queryset = PostDislike.objects.all() + serializer_class = PostDislikeSerializer + permission_classes = [permissions.IsAuthenticated] + + def create(self, request, *args, **kwargs): + post_id = request.data.get("post") + post = get_object_or_404(Post, id=post_id) + user = request.user + + PostLike.objects.filter(post=post, user=user).delete() + + existing_dislike = PostDislike.objects.filter(post=post, user=user) + if existing_dislike.exists(): + existing_dislike.delete() + return response.Response({"message": "Dislike removed"}, status=status.HTTP_200_OK) + + dislike = PostDislike.objects.create(post=post, user=user) + serializer = self.get_serializer(dislike) + + return response.Response(serializer.data, status=status.HTTP_201_CREATED) + + +__all__ = ("PostDislikeViewSet", ) diff --git a/apps/blog/api_endpoints/blog/PostLike/__init__.py b/apps/blog/api_endpoints/blog/PostLike/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostLike/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/blog/api_endpoints/blog/PostLike/serializers.py b/apps/blog/api_endpoints/blog/PostLike/serializers.py new file mode 100644 index 0000000..3dba64a --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostLike/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from apps.blog.models import PostLike + + +class PostLikeSerializer(serializers.ModelSerializer): + class Meta: + model = PostLike + fields = ["id", "user", "post"] diff --git a/apps/blog/api_endpoints/blog/PostLike/tests.py b/apps/blog/api_endpoints/blog/PostLike/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/blog/api_endpoints/blog/PostLike/views.py b/apps/blog/api_endpoints/blog/PostLike/views.py new file mode 100644 index 0000000..98de276 --- /dev/null +++ b/apps/blog/api_endpoints/blog/PostLike/views.py @@ -0,0 +1,31 @@ +from django.shortcuts import get_object_or_404 + +from rest_framework import viewsets, response, status, permissions + +from apps.blog.models import PostLike, PostDislike, Post +from .serializers import PostLikeSerializer + + +class PostLikeViewSet(viewsets.ModelViewSet): + queryset = PostLike.objects.all() + serializer_class = PostLikeSerializer + permission_classes = [permissions.IsAuthenticated] + + def create(self, request, *args, **kwargs): + post_id = request.data.get("post") + post = get_object_or_404(Post, id=post_id) + user = request.user + + PostDislike.objects.filter(post=post, user=user).delete() + + existing_like = PostLike.objects.filter(post=post, user=user) + if existing_like.exists(): + existing_like.delete() + return response.Response({"message": "Like removed"}, status=status.HTTP_200_OK) + + like = PostLike.objects.create(post=post, user=user) + serializer = self.get_serializer(like) + + return response.Response(serializer.data, status=status.HTTP_201_CREATED) + +__all__ = ("PostLikeViewSet", ) diff --git a/apps/blog/api_endpoints/blog/__init__.py b/apps/blog/api_endpoints/blog/__init__.py new file mode 100644 index 0000000..b689173 --- /dev/null +++ b/apps/blog/api_endpoints/blog/__init__.py @@ -0,0 +1,5 @@ +from .Post import * # noqa +from .PostComment import * # noqa +from .PostCommentLike import * # noqa +from .PostDislike import * # noqa +from .PostLike import * # noqa diff --git a/apps/blog/models.py b/apps/blog/models.py index 75c7a0c..620cab2 100644 --- a/apps/blog/models.py +++ b/apps/blog/models.py @@ -2,6 +2,7 @@ from django.db import models from django.urls import reverse from django.utils.text import slugify + from apps.shared.models import TimestempedAbstractModel from apps.shared.utils import get_random_text from .managers import PublishedManager @@ -29,7 +30,7 @@ class Post(TimestempedAbstractModel): published = PublishedManager() def delete(self, *args, **kwargs): - print(self.post_comments.all().delete()) + self.post_comments.all().delete() return super().delete(*args, **kwargs) class Meta: diff --git a/apps/blog/sitemaps.py b/apps/blog/sitemaps.py index bb91bca..35b32b0 100644 --- a/apps/blog/sitemaps.py +++ b/apps/blog/sitemaps.py @@ -7,7 +7,7 @@ class PostSitemap(Sitemap): priority = 0.9 def items(self): - return Post.published.all() + return Post.published.filter(is_active=True) def lastmod(self, obj): return obj.updated_at diff --git a/apps/users/api_endpoints/__init__.py b/apps/users/api_endpoints/__init__.py new file mode 100644 index 0000000..97e8f45 --- /dev/null +++ b/apps/users/api_endpoints/__init__.py @@ -0,0 +1,8 @@ +from rest_framework import routers + +from .users import UserViewSet, UserProfileViewSet + + +router = routers.DefaultRouter() +router.register("user", UserViewSet) +router.register("user_profile", UserProfileViewSet) diff --git a/apps/users/api_endpoints/users/User/__init__.py b/apps/users/api_endpoints/users/User/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/users/api_endpoints/users/User/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/users/api_endpoints/users/User/permissions.py b/apps/users/api_endpoints/users/User/permissions.py new file mode 100644 index 0000000..c69ae7c --- /dev/null +++ b/apps/users/api_endpoints/users/User/permissions.py @@ -0,0 +1,10 @@ +from rest_framework import permissions + + +class IsOwnerPermission(permissions.BasePermission): + """ + If user is owner + """ + + def has_object_permission(self, request, view, obj): + return obj == request.user diff --git a/apps/users/api_endpoints/users/User/serializers.py b/apps/users/api_endpoints/users/User/serializers.py new file mode 100644 index 0000000..9aed973 --- /dev/null +++ b/apps/users/api_endpoints/users/User/serializers.py @@ -0,0 +1,57 @@ +from rest_framework import serializers + +from apps.users.models import User, UserProfile + + +class MiniUserProfileSerializer(serializers.ModelSerializer): + class Meta: + model = UserProfile + fields = [ + "id", + "avatar", + "bio", + ] + + +class UserSerializer(serializers.ModelSerializer): + profiles = MiniUserProfileSerializer(read_only=True) + password = serializers.CharField(write_only=True, required=True) + password_confirm = serializers.CharField(write_only=True, required=True) + + class Meta: + model = User + fields = [ + "id", + "first_name", + "last_name", + "username", + "email", + "password", + "password_confirm", + "is_active", + "is_superuser", + "is_staff", + "post_count", + "profiles", + "created_at", + "updated_at", + ] + extra_kwargs = {"password": {"write_only": True}} + + def validate(self, attrs): + "Confirmation passwords" + + if attrs['password'] != attrs['password_confirm']: + raise serializers.ValidationError({"password": "Password didnt match!"}) + return attrs + + + def create(self, validated_data): + "Save a hashed password" + + validated_data.pop("password_confirm") + password = validated_data.pop("password") + user = User(**validated_data) + user.set_password(password) + user.save() + return user diff --git a/apps/users/api_endpoints/users/User/tests.py b/apps/users/api_endpoints/users/User/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/users/api_endpoints/users/User/views.py b/apps/users/api_endpoints/users/User/views.py new file mode 100644 index 0000000..bdd529e --- /dev/null +++ b/apps/users/api_endpoints/users/User/views.py @@ -0,0 +1,23 @@ +from rest_framework import viewsets, permissions +from rest_framework_simplejwt import authentication + +from apps.users.models import User +from .serializers import UserSerializer +from .permissions import IsOwnerPermission + + +class UserViewSet(viewsets.ModelViewSet): + queryset = User.objects.all() + serializer_class = UserSerializer + authentication_classes = [authentication.JWTAuthentication] + + def get_permissions(self): + if self.action == 'create': + return [permissions.AllowAny()] + + if self.action in ['retrieve', 'update', 'partial_update', 'destroy']: + return [permissions.IsAuthenticated(), permissions.IsAdminUser, IsOwnerPermission()] + + return [permissions.IsAuthenticated()] + +__all__ = ("UserViewSet", ) diff --git a/apps/users/api_endpoints/users/UserProfile/__init__.py b/apps/users/api_endpoints/users/UserProfile/__init__.py new file mode 100644 index 0000000..1da4c1c --- /dev/null +++ b/apps/users/api_endpoints/users/UserProfile/__init__.py @@ -0,0 +1 @@ +from .views import * # noqa \ No newline at end of file diff --git a/apps/users/api_endpoints/users/UserProfile/serializers.py b/apps/users/api_endpoints/users/UserProfile/serializers.py new file mode 100644 index 0000000..0dd54e3 --- /dev/null +++ b/apps/users/api_endpoints/users/UserProfile/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from apps.users.models import UserProfile + + +class UserProfileSerializer(serializers.ModelSerializer): + class Meta: + model = UserProfile + fields = ["id", "avatar", "bio", "user", "created_at", "updated_at"] diff --git a/apps/users/api_endpoints/users/UserProfile/tests.py b/apps/users/api_endpoints/users/UserProfile/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/users/api_endpoints/users/UserProfile/views.py b/apps/users/api_endpoints/users/UserProfile/views.py new file mode 100644 index 0000000..eee4d15 --- /dev/null +++ b/apps/users/api_endpoints/users/UserProfile/views.py @@ -0,0 +1,11 @@ +from rest_framework import viewsets + +from apps.users.models import UserProfile +from .serializers import UserProfileSerializer + + +class UserProfileViewSet(viewsets.ModelViewSet): + queryset = UserProfile.objects.all() + serializer_class = UserProfileSerializer + +__all__ = ("UserProfileViewSet", ) diff --git a/apps/users/api_endpoints/users/__init__.py b/apps/users/api_endpoints/users/__init__.py new file mode 100644 index 0000000..09010fe --- /dev/null +++ b/apps/users/api_endpoints/users/__init__.py @@ -0,0 +1,2 @@ +from .User import * # noqa +from .UserProfile import * # noqa \ No newline at end of file diff --git a/apps/users/models.py b/apps/users/models.py index 7c7b22d..cb76d94 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -1,7 +1,10 @@ from django.utils.translation import gettext_lazy as _ from django.contrib.auth.models import AbstractUser -from apps.shared.models import TimestempedAbstractModel from django.db import models +from apps.shared.models import TimestempedAbstractModel +from .utils import processor_iamge + +from PIL import Image class User(TimestempedAbstractModel, AbstractUser): @@ -11,11 +14,11 @@ class User(TimestempedAbstractModel, AbstractUser): def post_count(self): return self.posts.count - def get_user_avatar_url(self): - return self.profiles.avatar.url + def get_user_avatar_url(self) -> str: + return str(self.profiles.avatar.url) - def get_user_bio(self): - bio = self.profiles.bio + def get_user_bio(self) -> str: + bio = str(self.profiles.bio) if bio: return bio return "" @@ -52,3 +55,8 @@ class Meta: def __str__(self) -> str: return self.user.username + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + + processor_iamge(self.avatar.path) diff --git a/apps/users/urls.py b/apps/users/urls.py index 5c1a139..be2a414 100644 --- a/apps/users/urls.py +++ b/apps/users/urls.py @@ -1,5 +1,6 @@ -from django.urls import path +from django.urls import path, include +from .api_endpoints import router from . import views from rest_framework_simplejwt.views import ( @@ -19,6 +20,5 @@ views.UserProfilePageView.as_view(), name="user_profile", ), - path('api/token/', TokenObtainPairView.as_view(), name="token_obtain_pair"), - path('api/token/refresh/', TokenRefreshView.as_view(), name="token_refresh"), + ] diff --git a/apps/users/utils.py b/apps/users/utils.py new file mode 100644 index 0000000..53d1c6a --- /dev/null +++ b/apps/users/utils.py @@ -0,0 +1,8 @@ +from PIL import Image + + +def processor_iamge(img_path, width_size: int = 300, height_size: int = 300): + img = Image.open(img_path) + max_size = (width_size, height_size) + img.thumbnail(max_size, Image.LANCZOS) + img.save(img_path) diff --git a/core/settings/base.py b/core/settings/base.py index bdf1b1e..8331ec1 100644 --- a/core/settings/base.py +++ b/core/settings/base.py @@ -98,3 +98,5 @@ AUTH_USER_MODEL = "users.User" SITE_ID = 1 + +DEFAULT_FILE_STORAGE = "django.core/files.storage.FileSystemStorage" diff --git a/core/urls.py b/core/urls.py index 30b26cb..e0a56d7 100644 --- a/core/urls.py +++ b/core/urls.py @@ -5,15 +5,23 @@ from django.contrib import admin from django.urls import path, include from django.views.generic import TemplateView - from django.contrib.sitemaps.views import sitemap + from apps.blog.sitemaps import PostSitemap +from apps.users.api_endpoints import router as users_api_router +from apps.blog.api_endpoints import router as blog_api_router + +from rest_framework_simplejwt.views import ( + TokenObtainPairView, + TokenRefreshView, +) sitemaps = { "posts": PostSitemap, } +# URLs urlpatterns = [ path("admin/", admin.site.urls), path("", include("apps.blog.urls", namespace="blog")), @@ -27,6 +35,14 @@ ), ] +# API Endpoints +urlpatterns += [ + path("api/token", TokenObtainPairView.as_view(), name="token_obtain_pair"), + path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), + path("api/v1/users/", include(users_api_router.urls)), + path("api/v1/blogs/", include(blog_api_router.urls)) +] + if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/media/avatars/2.jpg b/media/avatars/2.jpg new file mode 100644 index 0000000..d6f7742 Binary files /dev/null and b/media/avatars/2.jpg differ diff --git a/media/avatars/channels4_profile.jpg b/media/avatars/channels4_profile.jpg deleted file mode 100644 index 089d813..0000000 Binary files a/media/avatars/channels4_profile.jpg and /dev/null differ diff --git a/media/avatars/default/logo.png b/media/avatars/default/logo.png index 0288d71..258decc 100644 Binary files a/media/avatars/default/logo.png and b/media/avatars/default/logo.png differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3ab295b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,26 @@ +[tool.poetry] +name = "blog app" +version = "0.1.0" +description = "Best blog app project for django" +authors = ["Akromjon <152626511+RustamovAkrom@users.noreply.github.com>"] +license = "MIT" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" +cryptography = "^43.0.3" +django-appconf = "^1.0.6" +django-sitemaps = "^2.0.1" +djangorestframework = "^3.15.2" +djangorestframework-simplejwt = "^5.3.1" +gunicorn = "^23.0.0" +markdown2 = {extras = ["all"], version = "^2.5.1"} +pillow = "^11.0.0" +psycopg2-binary = "^2.9.10" +python-dotenv = "^1.0.1" +django-filter = "^24.3" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.dev.txt b/requirements.dev.txt deleted file mode 100644 index 845a3d4..0000000 --- a/requirements.dev.txt +++ /dev/null @@ -1,26 +0,0 @@ -asgiref==3.8.1 -cffi==1.17.1 -cryptography==43.0.3 -Django==5.1.1 -django-appconf==1.0.6 -django_sitemaps==2.0.1 -djangorestframework==3.15.2 -djangorestframework-simplejwt==5.3.1 -gunicorn==23.0.0 -latex2mathml==3.77.0 -lxml==5.3.0 -markdown2==2.5.1 -packaging==24.2 -pillow==10.4.0 -psycopg2==2.9.10 -psycopg2-binary==2.9.10 -pycparser==2.22 -Pygments==2.18.0 -PyJWT==2.9.0 -python-dotenv==1.0.1 -PyYAML==6.0.2 -six==1.16.0 -sqlparse==0.5.1 -svgwrite==1.4.3 -tzdata==2024.2 -wavedrom==2.0.3.post3 diff --git a/requirements.txt b/requirements.txt index cfa8f24..73ed40d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,5 +8,4 @@ gunicorn==23.0.0 markdown2==2.5.1 pillow==10.4.0 psycopg2-binary==2.9.10 -mysqlclient python-dotenv==1.0.1 diff --git a/templates/blog/home.html b/templates/blog/home.html index e2e98cc..05b72dc 100644 --- a/templates/blog/home.html +++ b/templates/blog/home.html @@ -23,7 +23,7 @@