Browse Source

Add community module

wavesign
NinjaKelly 2 months ago
parent
commit
efe45e4fed
10 changed files with 350 additions and 0 deletions
  1. +0
    -0
      Community/__init__.py
  2. +3
    -0
      Community/admin.py
  3. +6
    -0
      Community/apps.py
  4. +86
    -0
      Community/migrations/0001_initial.py
  5. +67
    -0
      Community/migrations/0002_initial.py
  6. +0
    -0
      Community/migrations/__init__.py
  7. +36
    -0
      Community/models.py
  8. +3
    -0
      Community/tests.py
  9. +15
    -0
      Community/urls.py
  10. +134
    -0
      Community/views.py

+ 0
- 0
Community/__init__.py View File


+ 3
- 0
Community/admin.py View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

+ 6
- 0
Community/apps.py View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class CommunityConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "Community"

+ 86
- 0
Community/migrations/0001_initial.py View File

@ -0,0 +1,86 @@
# Generated by Django 5.2 on 2025-05-30 01:17
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Comment",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("content", models.TextField()),
("created_at", models.DateTimeField(auto_now_add=True)),
],
),
migrations.CreateModel(
name="Favorite",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
],
),
migrations.CreateModel(
name="Like",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
],
),
migrations.CreateModel(
name="Post",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("content", models.TextField(verbose_name="内容")),
(
"image",
models.ImageField(blank=True, null=True, upload_to="post_images/"),
),
(
"video",
models.FileField(blank=True, null=True, upload_to="post_videos/"),
),
("like_count", models.PositiveIntegerField(default=0)),
("comment_count", models.PositiveIntegerField(default=0)),
("favorite_count", models.PositiveIntegerField(default=0)),
("created_at", models.DateTimeField(auto_now_add=True)),
],
),
]

+ 67
- 0
Community/migrations/0002_initial.py View File

@ -0,0 +1,67 @@
# Generated by Django 5.2 on 2025-05-30 01:17
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("Community", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name="comment",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="favorite",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="like",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="post",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="like",
name="post",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="Community.post"
),
),
migrations.AddField(
model_name="favorite",
name="post",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="Community.post"
),
),
migrations.AddField(
model_name="comment",
name="post",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="Community.post"
),
),
]

+ 0
- 0
Community/migrations/__init__.py View File


+ 36
- 0
Community/models.py View File

@ -0,0 +1,36 @@
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings # 使用 Django 的配置抽象层
# 帖子模型
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.TextField(verbose_name="内容")
image = models.ImageField(upload_to='post_images/', blank=True, null=True)
video = models.FileField(upload_to='post_videos/', blank=True, null=True)
like_count = models.PositiveIntegerField(default=0) # 👍 新增点赞字段
comment_count = models.PositiveIntegerField(default=0) # 👍 新增评论字段
favorite_count = models.PositiveIntegerField(default=0) # 👍 新增点赞字段
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user.username} 的帖子"
# 互动模型(点赞、评论、收藏)
class Like(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Comment(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Favorite(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)

+ 3
- 0
Community/tests.py View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

+ 15
- 0
Community/urls.py View File

@ -0,0 +1,15 @@
from django.urls import re_path as url
from . import views
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path ('', views.post_list, name='community'), # 首页就是帖子列表
path('create_post/', views.create_post, name='create_post'), # 专用于发布逻辑
path ('post_list/', views.post_list, name='post_list'), # 浏览已发布帖子
path('like_post/<int:post_id>/', views.like_post, name='like_post'), # 点赞帖子
path('comment_post/<int:post_id>/', views.comment_post, name='comment_post'), # 评论帖子
path('favorite_post/<int:post_id>/', views.favorite_post, name='favorite_post'), # 收藏帖子
path('toggle_follow/<int:user_id>/', views.toggle_follow, name='toggle_follow'), # 关注
]

+ 134
- 0
Community/views.py View File

@ -0,0 +1,134 @@
from django.shortcuts import render, redirect
from .models import Post, Like, Comment, Favorite
from MyPage.models import Follow
from users.models import CustomUser
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
def index(request):
posts = Post.objects.all().order_by('-created_at')
return render(request, 'Community.html', {'posts': posts})
@login_required(login_url='login')
@csrf_exempt
def create_post(request):
if request.method == 'POST':
content = request.POST.get('content', '').strip()
image = request.FILES.get('image')
video = request.FILES.get('video')
if content or image or video:
try:
post = Post.objects.create(
user=request.user,
content=content,
image=image,
video=video
)
print("✅ 帖子成功写入数据库!ID:", post.id)
except Exception as e:
print("❌ 帖子写入失败:", e)
else:
print("⚠️ 无内容、图片或视频,跳过写入。")
return redirect('community')
# GET 请求展示帖子列表
posts = Post.objects.all().order_by('-created_at')
return render(request, 'Community.html', {'posts': posts})
# 浏览已发布帖子
def post_list(request):
posts = Post.objects.all().order_by('-created_at')
return render(request, 'Community.html', {'posts': posts})
@login_required(login_url='login')
@csrf_exempt
def like_post(request, post_id):
user = request.user
try:
post = Post.objects.get(id=post_id)
# 检查是否已点赞
if Like.objects.filter(user=user, post=post).exists():
return JsonResponse({'success': False, 'message': '已点赞'})
# 没有则创建记录
Like.objects.create(user=user, post=post)
post.like_count += 1
post.save()
return JsonResponse({'success': True, 'likes': post.like_count})
except Post.DoesNotExist:
return JsonResponse({'success': False, 'error': '帖子不存在'}, status=404)
@login_required(login_url='login')
@csrf_exempt
def comment_post(request, post_id):
if request.method == 'POST':
content = request.POST.get('content', '').strip()
if not content:
return JsonResponse({'success': False, 'message': '评论不能为空'})
try:
post = Post.objects.get(id=post_id)
comment = Comment.objects.create(user=request.user, post=post, content=content)
post.comment_count += 1
post.save()
return JsonResponse({
'success': True,
'username': comment.user.username,
'content': comment.content,
'created_at': comment.created_at.strftime('%Y-%m-%d %H:%M:%S'),
'comment_count': post.comment_count
})
except Post.DoesNotExist:
return JsonResponse({'success': False, 'error': '帖子不存在'}, status=404)
@login_required(login_url='login')
@csrf_exempt
def favorite_post(request, post_id):
user = request.user
try:
post = Post.objects.get(id=post_id)
# 检查是否已收藏
if Favorite.objects.filter(user=user, post=post).exists():
return JsonResponse({'success': False, 'message': '已收藏'})
# 没有则创建记录
Favorite.objects.create(user=user, post=post)
post.favorite_count += 1
post.save()
return JsonResponse({'success': True, 'favorites': post.favorite_count})
except Post.DoesNotExist:
return JsonResponse({'success': False, 'error': '帖子不存在'}, status=404)
@login_required(login_url='login')
@csrf_exempt
def toggle_follow(request, user_id):
follower = request.user
try:
followed = CustomUser.objects.get(id=user_id)
if follower == followed:
return JsonResponse({'success': False, 'message': '不能关注自己'})
existing = Follow.objects.filter(follower=follower, followed=followed)
if existing.exists():
existing.delete()
return JsonResponse({'success': True, 'following': False, 'message': '已取消关注'})
else:
Follow.objects.create(follower=follower, followed=followed)
return JsonResponse({'success': True, 'following': True, 'message': '关注成功'})
except CustomUser.DoesNotExist:
return JsonResponse({'success': False, 'message': '用户不存在'})
def post_list(request):
posts = Post.objects.all().order_by('-created_at')
user = request.user
for post in posts:
post.is_followed = False
if user.is_authenticated and post.user != user:
post.is_followed = Follow.objects.filter(follower=user, followed=post.user).exists()
return render(request, 'Community.html', {'posts': posts})

Loading…
Cancel
Save