diff --git a/.env.example b/.env.example deleted file mode 100644 index 211e03e..0000000 --- a/.env.example +++ /dev/null @@ -1,8 +0,0 @@ -POSTGRES_USER=lspp -POSTGRES_PASSWORD=lspp1234 -POSTGRES_HOST=localhost -POSTGRES_PORT=5432 -POSTGRES_DB=lspp_db -EMAIL_PASSWORD= -EMAIL_USER= -EMAIL_HOST=smtp.gmail.com diff --git a/backend/urls.py b/backend/urls.py index 970dc6d..c48cfdd 100644 --- a/backend/urls.py +++ b/backend/urls.py @@ -22,6 +22,7 @@ urlpatterns = [ path("admin/", admin.site.urls), path("api/auth/", include("authentication.urls")), + path("api/blogs/", include("blogs.urls")), ] if settings.DEBUG: diff --git a/blogs/admin.py b/blogs/admin.py index 8c38f3f..8be3ba9 100644 --- a/blogs/admin.py +++ b/blogs/admin.py @@ -1,3 +1,8 @@ from django.contrib import admin +from .models import * + # Register your models here. +admin.site.register(Posts) +admin.site.register(Comments) +admin.site.register(Likes) diff --git a/blogs/migrations/0001_initial.py b/blogs/migrations/0001_initial.py new file mode 100644 index 0000000..bb3da5d --- /dev/null +++ b/blogs/migrations/0001_initial.py @@ -0,0 +1,93 @@ +# Generated by Django 4.2.6 on 2023-10-28 08:21 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Users", + fields=[ + ("user_id", models.AutoField(primary_key=True, serialize=False)), + ("username", models.CharField(max_length=50)), + ("email", models.EmailField(max_length=254, unique=True)), + ("password", models.CharField(max_length=10)), + ], + ), + migrations.CreateModel( + name="Posts", + fields=[ + ("post_id", models.AutoField(primary_key=True, serialize=False)), + ("title", models.CharField(max_length=50)), + ("content", models.TextField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="blogs.users" + ), + ), + ], + ), + migrations.CreateModel( + name="Likes", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now=True)), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="blogs.posts" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="blogs.users" + ), + ), + ], + ), + migrations.CreateModel( + name="Comments", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("c_content", models.TextField()), + ("created_at", models.DateTimeField(auto_now=True)), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="blogs.posts" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="blogs.users" + ), + ), + ], + ), + ] diff --git a/blogs/migrations/0002_alter_comments_post_alter_comments_user_and_more.py b/blogs/migrations/0002_alter_comments_post_alter_comments_user_and_more.py new file mode 100644 index 0000000..928691c --- /dev/null +++ b/blogs/migrations/0002_alter_comments_post_alter_comments_user_and_more.py @@ -0,0 +1,63 @@ +# Generated by Django 4.2.6 on 2023-10-28 15:52 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("blogs", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="comments", + name="post", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="comment_post", + to="blogs.posts", + ), + ), + migrations.AlterField( + model_name="comments", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="comment_user", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AlterField( + model_name="likes", + name="post", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="like_post", + to="blogs.posts", + ), + ), + migrations.AlterField( + model_name="likes", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="like_user", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AlterField( + model_name="posts", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="post", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.DeleteModel( + name="Users", + ), + ] diff --git a/blogs/models.py b/blogs/models.py index 71a8362..19f78c1 100644 --- a/blogs/models.py +++ b/blogs/models.py @@ -1,3 +1,35 @@ +from datetime import datetime + +from django.conf import settings +from django.contrib.auth.models import User from django.db import models # Create your models here. + + +class Posts(models.Model): + post_id = models.AutoField(primary_key=True) + title = models.CharField(max_length=50, blank=False) + content = models.TextField(blank=False) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='post') #reference from Users + + def __str__(self): + return self.title + + +class Comments(models.Model): + post = models.ForeignKey(Posts, on_delete= models.CASCADE,related_name='comment_post') #reference from Posts + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE, related_name='comment_user') #reference from Users + c_content = models.TextField() + created_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"{self.user}/{self.post}" + + +class Likes(models.Model): + post = models.ForeignKey(Posts, on_delete= models.CASCADE, related_name='like_post') #refrence from Posts + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE, related_name='like_user') #reference from Users + created_at = models.DateTimeField(auto_now=True) diff --git a/blogs/serializers.py b/blogs/serializers.py new file mode 100644 index 0000000..5162667 --- /dev/null +++ b/blogs/serializers.py @@ -0,0 +1,39 @@ +from django.contrib.auth.models import User +from rest_framework import serializers + +from authentication.serializers import * + +from .models import * + + +class LikeSerializer(serializers.ModelSerializer): + class Meta: + model = Likes + fields = '__all__' + read_only_fields = ['user','post'] + +class CommentSerializer(serializers.ModelSerializer): + class Meta: + model = Comments + fields = '__all__' + read_only_fields = ['user'] + +class CommentEditSerializer(serializers.ModelSerializer): + class Meta: + model = Comments + fields = '__all__' + read_only_fields = ['user','post'] + +class PostSerializer(serializers.ModelSerializer): + comment_post = CommentSerializer(many=True) + like_post = LikeSerializer(many=True) + user = serializers.CharField() + class Meta: + model = Posts + fields = ('user','post_id','title','content','created_at','updated_at','comment_post','like_post') + +class CreatePostSerializer(serializers.ModelSerializer): + class Meta: + model = Posts + fields = ('user','title','content') + read_only_fields = ['user'] diff --git a/blogs/urls.py b/blogs/urls.py new file mode 100644 index 0000000..35ba010 --- /dev/null +++ b/blogs/urls.py @@ -0,0 +1,19 @@ +from django.urls import include, path + +from blogs.views import (CreateBlogView, CreateCommentView, EditCommentView, + GetBlogView, LikeCreateView, ReadCommentView, + ReadPostView) + +urlpatterns = [ + path('getblog',GetBlogView.as_view()), + path('readpost/',ReadPostView.as_view()), + path('createblog',CreateBlogView.as_view()), + path('createblog//',CreateBlogView.as_view()), + path('deleteblog/',CreateBlogView.as_view()), + path('createcomment',CreateCommentView.as_view()), + path('readcomment/', ReadCommentView.as_view()), + path('editcomment//',EditCommentView.as_view()), + path('deletecomment/',CreateCommentView.as_view()), + path('likepost/',LikeCreateView.as_view()), + path('unlikepost/',LikeCreateView.as_view()), +] diff --git a/blogs/views.py b/blogs/views.py index 91ea44a..03383ad 100644 --- a/blogs/views.py +++ b/blogs/views.py @@ -1,3 +1,270 @@ +from django.http import JsonResponse from django.shortcuts import render +from rest_framework.permissions import IsAuthenticated +from rest_framework.request import Request +from rest_framework.response import Response +from rest_framework.views import APIView -# Create your views here. +from blogs.serializers import (CommentEditSerializer, CommentSerializer, + CreatePostSerializer, LikeSerializer, + PostSerializer) +from core.response import CustomResponse as cr + +from .models import Comments, Likes, Posts + + +class GetBlogView(APIView): + serializer_class = PostSerializer + + def get(self, request: Request) -> Response: + """ + Get the information about a blog post. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + posts = Posts.objects.all() + serializer = self.serializer_class(posts, many=True) + return cr.success(data=serializer.data, message="Blogs fetched successfully!") + + +class CreateBlogView(APIView): + permission_classes=[IsAuthenticated] + + serializer_class = CreatePostSerializer + + def post(self, request: Request) -> Response: + + """ + Post a new blog. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + serializer = self.serializer_class(data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save(user = request.user) + + return cr.success(data = serializer.data, message= "New blog added successfully!") + + def put(self, request: Request, post_id) -> Response: + """ + Update the comments. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object containing the new access token. + """ + + post = Posts.objects.filter(post_id=post_id, user=request.user).first() + if not post: + return cr.error("Post not found.") + + serializer = self.serializer_class(post, data=request.data) + serializer.is_valid(raise_exception=True) + save = serializer.save(user = request.user) + + return cr.success(data = serializer.data, message= "Post updated successfully!") + + def delete(self, request: Request, post_id) -> Response: + + """ + Delete the posts. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + post = Posts.objects.filter(post_id=post_id, user=request.user).first() + if not post: + return cr.error(message="Post not found.") + + post.delete() + return cr.success(message="Post deleted successfully.") + + +class CreateCommentView(APIView): + + permission_classes = [IsAuthenticated] + + serializer_class = CommentSerializer + + def post(self, request: Request) -> Response: + """ + Post a new comment in a post. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + serializer = self.serializer_class(data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save(user = request.user) + + return cr.success(data = serializer.data, message= "New comment added successfully!") + + def delete(self, request: Request, id) -> Response: + + """ + Delete the comments. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + comment = Comments.objects.filter(id=id, user=request.user).first() + if not comment: + return cr.error(message="Comment not found.") + + comment.delete() + return cr.success(message="Comment deleted successfully.") + + +class EditCommentView(APIView): + + permission_classes = [IsAuthenticated] + + serializer_class = CommentEditSerializer + + def put(self, request: Request, id) -> Response: + """ + Update the comments. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + comment = Comments.objects.filter(id=id, user=request.user).first() + if not comment: + return cr.error(message="Comment not found.") + + serializer = self.serializer_class(comment, data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save() + + return cr.success(data = serializer.data, message= "Comment updated successfully!") + +class ReadPostView(APIView): + + serializer_class = PostSerializer + + def get(self, request: Request, post_id) -> Response: + """ + Get the information about a blog post. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + posts = Posts.objects.filter(post_id = post_id).first() + if not posts: + return cr.error(message="Post not found.") + serializer = self.serializer_class(posts) + return cr.success(data=serializer.data, message="Blog fetched successfully!") + + +class ReadCommentView(APIView): + + serializer_class = CommentSerializer + + def get(self, request: Request, id) -> Response: + """ + Get the information about a blog post. + + Args: + request (Request): The HTTP request object. + + Returns: + Response: The HTTP response object. + """ + + comment = Comments.objects.filter(id = id).first() + if not comment: + return cr.error(message="Comment not found.") + serializer = self.serializer_class(comment) + return cr.success(data=serializer.data, message="Comment fetched successfully!") + + +# class LikeCreateView(APIView): + +# permission_classes = [IsAuthenticated] + +# def post(self, request: Request, post_id) -> Response: + +# user = request.user +# post = Likes.objects.filter(post_id=post_id, user=user).filter() +# current_likes = post.user.count() +# if not post: +# post.user.add() + + +# existing_like = Likes.objects.filter(post_id=post_id, user=request.user).first() +# post = existing_like.post +# user = existing_like.user +# if not existing_like: +# serializer.save(user = user, post = post) +# return cr.success(data=serializer.data, message="Succefully liked a post.") + + +class LikeCreateView(APIView): + + permission_classes = [IsAuthenticated] + + def post(self, request, post_id): + + post = Posts.objects.filter(post_id=post_id).first() + user = request.user + + if not post: + return cr.error(message="Post not found.") + + like_exists = Likes.objects.filter(user=user, post=post).exists() + + if like_exists: + return cr.success(message='You have already liked this post.') + + like = Likes(user=user, post=post) + like.save() + + return cr.success(message='Post liked successfully.') + + def delete(self, request, post_id): + post = Posts.objects.filter(post_id=post_id).first() + user = request.user + + if not post: + return cr.error(message="Post not found.") + + like = Likes.objects.filter(user=user, post=post).first() + + if not like: + return cr.success(message='You have not liked this post.') + + like.delete() + + return cr.success(message='Like removed successfully.')