Browse Source

Add MyPage module

wavesign
NinjaKelly 2 months ago
parent
commit
849b348980
11 changed files with 317 additions and 0 deletions
  1. +0
    -0
      MyPage/__init__.py
  2. +3
    -0
      MyPage/admin.py
  3. +6
    -0
      MyPage/apps.py
  4. +15
    -0
      MyPage/forms.py
  5. +64
    -0
      MyPage/migrations/0001_initial.py
  6. +45
    -0
      MyPage/migrations/0002_initial.py
  7. +0
    -0
      MyPage/migrations/__init__.py
  8. +32
    -0
      MyPage/models.py
  9. +3
    -0
      MyPage/tests.py
  10. +10
    -0
      MyPage/urls.py
  11. +139
    -0
      MyPage/views.py

+ 0
- 0
MyPage/__init__.py View File


+ 3
- 0
MyPage/admin.py View File

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

+ 6
- 0
MyPage/apps.py View File

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

+ 15
- 0
MyPage/forms.py View File

@ -0,0 +1,15 @@
from django import forms
from users.models import CustomUser
from .models import UserProfile
# 表单上传更新
class ProfileUpdateForm(forms.ModelForm):
username = forms.CharField(max_length=150, required=True)
avatar = forms.ImageField(required=False)
personal_background = forms.ImageField(required=False)
page_background = forms.ImageField(required=False)
bio = forms.CharField(widget=forms.Textarea, required=False)
class Meta:
model = CustomUser
fields = ['username', 'avatar']

+ 64
- 0
MyPage/migrations/0001_initial.py View File

@ -0,0 +1,64 @@
# 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="Follow",
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="UserProfile",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("bio", models.TextField(blank=True, verbose_name="个人简介")),
(
"personal_background",
models.ImageField(
blank=True,
default="personal_backgrounds/default.png",
null=True,
upload_to="personal_backgrounds/",
verbose_name="个人资料背景",
),
),
(
"page_background",
models.ImageField(
blank=True,
default="page_backgrounds/default.png",
null=True,
upload_to="page_backgrounds/",
verbose_name="页面背景",
),
),
("updated_at", models.DateTimeField(auto_now=True)),
],
),
]

+ 45
- 0
MyPage/migrations/0002_initial.py View File

@ -0,0 +1,45 @@
# 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 = [
("MyPage", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name="follow",
name="followed",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="followers",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="follow",
name="follower",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="following",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="userprofile",
name="user",
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="profile",
to=settings.AUTH_USER_MODEL,
),
),
]

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


+ 32
- 0
MyPage/models.py View File

@ -0,0 +1,32 @@
from django.db import models
from django.conf import settings
from Community.models import Post # 假设帖子模型在 Community 应用中
from django.contrib.auth import get_user_model
User = get_user_model()
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.TextField(blank=True, verbose_name="个人简介")
personal_background = models.ImageField(upload_to='personal_backgrounds/', blank=True, null=True,
verbose_name="个人资料背景", default='personal_backgrounds/default.png')
page_background = models.ImageField(upload_to='page_backgrounds/', blank=True, null=True,
verbose_name="页面背景", default='page_backgrounds/default.png')
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.user.username} 的个人资料"
def get_user_posts(self):
return Post.objects.filter(user=self.user).order_by('-created_at')
class Follow(models.Model):
"""用于记录用户之间的关注关系"""
follower = models.ForeignKey(User, related_name='following', on_delete=models.CASCADE)
followed = models.ForeignKey(User, related_name='followers', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.follower.username} 关注了 {self.following.username}"

+ 3
- 0
MyPage/tests.py View File

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

+ 10
- 0
MyPage/urls.py View File

@ -0,0 +1,10 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.my_page_view, name='my_page'),
path('upload-avatar/', views.upload_avatar, name='upload_avatar'),
path('upload-banner/', views.upload_banner, name='upload_banner'),
path('upload-pagebg/', views.upload_page_background, name='upload_pagebg'),
path('delete_post/<int:post_id>/', views.delete_post, name='delete_post'),
]

+ 139
- 0
MyPage/views.py View File

@ -0,0 +1,139 @@
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import ProfileUpdateForm
from .models import UserProfile, Follow
from Community.models import Like, Comment, Post
from users.models import CustomUser
from Schedule.models import Event, Task
from datetime import datetime, timedelta
from django.http import JsonResponse
@login_required(login_url='login')
def my_page_view(request):
# 当前登录用户
user = request.user
profile = user.profile
# 上传、修改资料
if request.method == 'POST':
form = ProfileUpdateForm(request.POST, request.FILES, instance=user)
if form.is_valid():
# 保存 username(avatar 字段不能自动保存)
user.username = form.cleaned_data.get('username', user.username)
if request.FILES.get('avatar'):
user.avatar = request.FILES['avatar'] # ✅ 手动保存头像
user.save()
# 更新 UserProfile 的字段
profile.bio = request.POST.get('bio', '')
if 'personal_background' in request.FILES:
profile.personal_background = request.FILES['personal_background']
if 'page_background' in request.FILES:
profile.page_background = request.FILES['page_background']
profile.save()
return redirect('my_page')
else:
form = ProfileUpdateForm(instance=user)
# 我关注的人
follows = Follow.objects.filter(follower=user).select_related('followed')
# 我的帖子
my_posts = Post.objects.filter(user=user).order_by('-created_at')
# 我的点赞
liked_posts = Post.objects.filter(like__user=user).distinct()
# 我的收藏
favorited_posts = Post.objects.filter(favorite__user=user).distinct()
# 通知:别人点赞/评论了我的帖子
recent_likes = Like.objects.filter(post__user=user).exclude(user=user).select_related('user', 'post').order_by('-created_at')[:10]
recent_comments = Comment.objects.filter(post__user=user).exclude(user=user).select_related('user', 'post').order_by('-created_at')[:10]
# 获取今天以后的最近3条日程
now = datetime.now()
upcoming_events = Event.objects.filter(user=request.user).filter(
date__gt=now.date()
) | Event.objects.filter(
user=request.user,
date=now.date(),
time__gte=now.time()
)
upcoming_events = upcoming_events.order_by('date', 'time')[:3]
# 获取未完成任务(最近添加的3个)
recent_tasks = Task.objects.filter(
user=request.user,
completed=False
).order_by('-created_at')[:3]
return render(request, 'myPage.html', {
'form': form,
'user': user,
'profile': profile,
'follows': follows,
'my_posts': my_posts,
'liked_posts': liked_posts,
'favorited_posts': favorited_posts,
'recent_likes': recent_likes,
'recent_comments': recent_comments,
'upcoming_events': upcoming_events,
'recent_tasks': recent_tasks,
})
# 头像图片上传
def upload_avatar(request):
if request.method == 'POST' and request.user.is_authenticated:
user = request.user
if 'avatar' in request.FILES:
user.avatar = request.FILES['avatar']
user.save()
return JsonResponse({'success': True, 'avatar_url': user.avatar.url})
else:
return JsonResponse({'success': False, 'message': '没有接收到avatar文件'})
return JsonResponse({'success': False, 'message': '请求失败,必须为POST并登录'})
# 个人资料背景上传
def upload_banner(request):
if request.method == 'POST' and request.user.is_authenticated:
profile = request.user.profile
if 'personal_background' in request.FILES:
profile.personal_background = request.FILES['personal_background']
profile.save()
return JsonResponse({'success': True, 'bg_url': profile.personal_background.url})
else:
return JsonResponse({'success': False, 'message': '未收到文件'})
return JsonResponse({'success': False, 'message': '权限或方法错误'})
# 页面背景图片上传
def upload_page_background(request):
if request.method == 'POST' and request.user.is_authenticated:
profile = request.user.profile
if 'page_background' in request.FILES:
profile.page_background = request.FILES['page_background']
profile.save()
return JsonResponse({'success': True, 'bg_url': profile.page_background.url})
else:
return JsonResponse({'success': False, 'message': '未收到文件'})
return JsonResponse({'success': False, 'message': '权限或方法错误'})
# 删除帖子
def delete_post(request, post_id):
post = get_object_or_404(Post, id=post_id, user=request.user)
if request.method == 'POST':
post.delete()
messages.success(request, "帖子已删除!")
return redirect('my_page')

Loading…
Cancel
Save