diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..9e9a9cd --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://113.125.109.60:3306 + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..a1d791f --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,93 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..39587be --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3a3e668 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/webServer.iml b/.idea/webServer.iml new file mode 100644 index 0000000..b8ca984 --- /dev/null +++ b/.idea/webServer.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Server01/__init__.py b/Server01/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Server01/__pycache__/__init__.cpython-39.pyc b/Server01/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..c47f889 Binary files /dev/null and b/Server01/__pycache__/__init__.cpython-39.pyc differ diff --git a/Server01/__pycache__/admin.cpython-39.pyc b/Server01/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000..4a9dae6 Binary files /dev/null and b/Server01/__pycache__/admin.cpython-39.pyc differ diff --git a/Server01/__pycache__/apps.cpython-39.pyc b/Server01/__pycache__/apps.cpython-39.pyc new file mode 100644 index 0000000..5694090 Binary files /dev/null and b/Server01/__pycache__/apps.cpython-39.pyc differ diff --git a/Server01/__pycache__/models.cpython-39.pyc b/Server01/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000..9166377 Binary files /dev/null and b/Server01/__pycache__/models.cpython-39.pyc differ diff --git a/Server01/admin.py b/Server01/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/Server01/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/Server01/apps.py b/Server01/apps.py new file mode 100644 index 0000000..93a4c55 --- /dev/null +++ b/Server01/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class Server01Config(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "Server01" diff --git a/Server01/migrations/0001_initial.py b/Server01/migrations/0001_initial.py new file mode 100644 index 0000000..f462fc7 --- /dev/null +++ b/Server01/migrations/0001_initial.py @@ -0,0 +1,143 @@ +# Generated by Django 4.1 on 2023-07-09 04:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Post", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=64, verbose_name="标题")), + ( + "content", + models.TextField(max_length=3000, null=True, verbose_name="内容"), + ), + ( + "created_at", + models.DateTimeField(auto_now_add=True, verbose_name="创建时间"), + ), + ], + ), + migrations.CreateModel( + name="User", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("username", models.CharField(max_length=32, verbose_name="用户名")), + ("password", models.CharField(max_length=64, verbose_name="密码")), + ( + "avatar", + models.CharField( + default="http://localhost:8000/static/img/defaultAvatar.jpg", + max_length=64, + null=True, + verbose_name="头像", + ), + ), + ( + "signature", + models.CharField( + default="暂时没有个性签名~", + max_length=64, + null=True, + verbose_name="个性签名", + ), + ), + ( + "collected", + models.ManyToManyField( + blank=True, related_name="collected", to="Server01.post" + ), + ), + ( + "favorites", + models.ManyToManyField( + blank=True, related_name="favorite", to="Server01.post" + ), + ), + ( + "following", + models.ManyToManyField( + blank=True, related_name="followers", to="Server01.user" + ), + ), + ], + ), + migrations.AddField( + model_name="post", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="posts", + to="Server01.user", + ), + ), + migrations.CreateModel( + name="Comment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("content", models.TextField(max_length=3000, verbose_name="评论")), + ( + "created_at", + models.DateTimeField(auto_now_add=True, verbose_name="创建时间"), + ), + ( + "parent_comment", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="replies", + to="Server01.comment", + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="comments", + to="Server01.post", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="comments", + to="Server01.user", + ), + ), + ], + ), + ] diff --git a/Server01/migrations/0002_alter_user_avatar.py b/Server01/migrations/0002_alter_user_avatar.py new file mode 100644 index 0000000..143022b --- /dev/null +++ b/Server01/migrations/0002_alter_user_avatar.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1 on 2023-07-09 05:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="avatar", + field=models.CharField( + default="http://localhost:8000/static/img/defaultAvatar.jpg", + max_length=64, + verbose_name="头像", + ), + ), + ] diff --git a/Server01/migrations/0003_alter_user_avatar.py b/Server01/migrations/0003_alter_user_avatar.py new file mode 100644 index 0000000..e30ac0f --- /dev/null +++ b/Server01/migrations/0003_alter_user_avatar.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1 on 2023-07-09 07:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0002_alter_user_avatar"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="avatar", + field=models.CharField( + default="http://localhost:8000/static/img/avatar/defaultAvatar.jpg", + max_length=64, + verbose_name="头像", + ), + ), + ] diff --git a/Server01/migrations/0004_user_email.py b/Server01/migrations/0004_user_email.py new file mode 100644 index 0000000..6ceb89f --- /dev/null +++ b/Server01/migrations/0004_user_email.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1 on 2023-07-09 10:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0003_alter_user_avatar"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="email", + field=models.CharField( + default="123@123.com", max_length=32, verbose_name="邮箱" + ), + ), + ] diff --git a/Server01/migrations/0005_user_followed_alter_user_following.py b/Server01/migrations/0005_user_followed_alter_user_following.py new file mode 100644 index 0000000..473d09f --- /dev/null +++ b/Server01/migrations/0005_user_followed_alter_user_following.py @@ -0,0 +1,27 @@ +# Generated by Django 4.1 on 2023-07-09 13:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0004_user_email"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="followed", + field=models.ManyToManyField( + blank=True, related_name="focusOn", to="Server01.user" + ), + ), + migrations.AlterField( + model_name="user", + name="following", + field=models.ManyToManyField( + blank=True, related_name="beFocusOn", to="Server01.user" + ), + ), + ] diff --git a/Server01/migrations/0006_image_post_images.py b/Server01/migrations/0006_image_post_images.py new file mode 100644 index 0000000..e09a8e5 --- /dev/null +++ b/Server01/migrations/0006_image_post_images.py @@ -0,0 +1,42 @@ +# Generated by Django 4.1 on 2023-07-09 13:42 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0005_user_followed_alter_user_following"), + ] + + operations = [ + migrations.CreateModel( + name="Image", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("imagePath", models.CharField(max_length=32, verbose_name="帖子图片")), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="Server01.post" + ), + ), + ], + ), + migrations.AddField( + model_name="post", + name="images", + field=models.ManyToManyField( + blank=True, related_name="imgs", to="Server01.image" + ), + ), + ] diff --git a/Server01/migrations/0007_alter_image_imagepath_alter_user_avatar.py b/Server01/migrations/0007_alter_image_imagepath_alter_user_avatar.py new file mode 100644 index 0000000..2ce1c9d --- /dev/null +++ b/Server01/migrations/0007_alter_image_imagepath_alter_user_avatar.py @@ -0,0 +1,27 @@ +# Generated by Django 4.1 on 2023-07-09 13:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0006_image_post_images"), + ] + + operations = [ + migrations.AlterField( + model_name="image", + name="imagePath", + field=models.CharField(max_length=256, verbose_name="帖子图片"), + ), + migrations.AlterField( + model_name="user", + name="avatar", + field=models.CharField( + default="http://localhost:8000/static/img/avatar/defaultAvatar.jpg", + max_length=256, + verbose_name="头像", + ), + ), + ] diff --git a/Server01/migrations/0008_alter_user_collected.py b/Server01/migrations/0008_alter_user_collected.py new file mode 100644 index 0000000..f46235c --- /dev/null +++ b/Server01/migrations/0008_alter_user_collected.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1 on 2023-07-09 13:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0007_alter_image_imagepath_alter_user_avatar"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="collected", + field=models.ManyToManyField( + blank=True, related_name="collectedPosts", to="Server01.post" + ), + ), + ] diff --git a/Server01/migrations/0009_alter_user_favorites.py b/Server01/migrations/0009_alter_user_favorites.py new file mode 100644 index 0000000..27b81ed --- /dev/null +++ b/Server01/migrations/0009_alter_user_favorites.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1 on 2023-07-09 13:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0008_alter_user_collected"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="favorites", + field=models.ManyToManyField( + blank=True, related_name="favoritePosts", to="Server01.post" + ), + ), + ] diff --git a/Server01/migrations/0010_remove_post_images_alter_image_post.py b/Server01/migrations/0010_remove_post_images_alter_image_post.py new file mode 100644 index 0000000..f235388 --- /dev/null +++ b/Server01/migrations/0010_remove_post_images_alter_image_post.py @@ -0,0 +1,27 @@ +# Generated by Django 4.1 on 2023-07-09 13:56 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("Server01", "0009_alter_user_favorites"), + ] + + operations = [ + migrations.RemoveField( + model_name="post", + name="images", + ), + migrations.AlterField( + model_name="image", + name="post", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="imgs", + to="Server01.post", + ), + ), + ] diff --git a/Server01/migrations/__init__.py b/Server01/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Server01/migrations/__pycache__/0001_initial.cpython-39.pyc b/Server01/migrations/__pycache__/0001_initial.cpython-39.pyc new file mode 100644 index 0000000..ac8d043 Binary files /dev/null and b/Server01/migrations/__pycache__/0001_initial.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0002_alter_user_avatar.cpython-39.pyc b/Server01/migrations/__pycache__/0002_alter_user_avatar.cpython-39.pyc new file mode 100644 index 0000000..4399eaf Binary files /dev/null and b/Server01/migrations/__pycache__/0002_alter_user_avatar.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0003_alter_user_avatar.cpython-39.pyc b/Server01/migrations/__pycache__/0003_alter_user_avatar.cpython-39.pyc new file mode 100644 index 0000000..fa6e69e Binary files /dev/null and b/Server01/migrations/__pycache__/0003_alter_user_avatar.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0004_user_email.cpython-39.pyc b/Server01/migrations/__pycache__/0004_user_email.cpython-39.pyc new file mode 100644 index 0000000..8fe946e Binary files /dev/null and b/Server01/migrations/__pycache__/0004_user_email.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0005_user_followed_alter_user_following.cpython-39.pyc b/Server01/migrations/__pycache__/0005_user_followed_alter_user_following.cpython-39.pyc new file mode 100644 index 0000000..7ade043 Binary files /dev/null and b/Server01/migrations/__pycache__/0005_user_followed_alter_user_following.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0006_image_post_images.cpython-39.pyc b/Server01/migrations/__pycache__/0006_image_post_images.cpython-39.pyc new file mode 100644 index 0000000..0ac43e6 Binary files /dev/null and b/Server01/migrations/__pycache__/0006_image_post_images.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0007_alter_image_imagepath_alter_user_avatar.cpython-39.pyc b/Server01/migrations/__pycache__/0007_alter_image_imagepath_alter_user_avatar.cpython-39.pyc new file mode 100644 index 0000000..7a8f15f Binary files /dev/null and b/Server01/migrations/__pycache__/0007_alter_image_imagepath_alter_user_avatar.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0008_alter_user_collected.cpython-39.pyc b/Server01/migrations/__pycache__/0008_alter_user_collected.cpython-39.pyc new file mode 100644 index 0000000..cf6a035 Binary files /dev/null and b/Server01/migrations/__pycache__/0008_alter_user_collected.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0009_alter_user_favorites.cpython-39.pyc b/Server01/migrations/__pycache__/0009_alter_user_favorites.cpython-39.pyc new file mode 100644 index 0000000..90b5240 Binary files /dev/null and b/Server01/migrations/__pycache__/0009_alter_user_favorites.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/0010_remove_post_images_alter_image_post.cpython-39.pyc b/Server01/migrations/__pycache__/0010_remove_post_images_alter_image_post.cpython-39.pyc new file mode 100644 index 0000000..ddbb6c0 Binary files /dev/null and b/Server01/migrations/__pycache__/0010_remove_post_images_alter_image_post.cpython-39.pyc differ diff --git a/Server01/migrations/__pycache__/__init__.cpython-39.pyc b/Server01/migrations/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..6939b0d Binary files /dev/null and b/Server01/migrations/__pycache__/__init__.cpython-39.pyc differ diff --git a/Server01/models.py b/Server01/models.py new file mode 100644 index 0000000..89295fe --- /dev/null +++ b/Server01/models.py @@ -0,0 +1,44 @@ +from django.db import models + + +class User(models.Model): + """ 用户表 """ + email = models.CharField(max_length=32, verbose_name='邮箱', null=False, default='123@123.com') + username = models.CharField(max_length=32, verbose_name='用户名', null=False) + password = models.CharField(max_length=64, verbose_name='密码', null=False) + avatar = models.CharField(max_length=256, verbose_name='头像', null=False, + default='http://localhost:8000/static/img/avatar/defaultAvatar.jpg') + signature = models.CharField(max_length=64, verbose_name='个性签名', default='暂时没有个性签名~', null=True) + following = models.ManyToManyField('self', symmetrical=False, blank=True, related_name='beFocusOn') + followed = models.ManyToManyField('self', symmetrical=False, blank=True, related_name='focusOn') + favorites = models.ManyToManyField('Post', blank=True, related_name='favoritePosts') + collected = models.ManyToManyField('Post', blank=True, related_name='collectedPosts') + + +class Post(models.Model): + """ 帖子表 """ + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts') + title = models.CharField(max_length=64, verbose_name='标题', null=False) + content = models.TextField(max_length=3000, verbose_name='内容', null=True) + created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') + + def delete(self, *args, **kwargs): + # 删除关联的帖子图片 + self.imgs.all().delete() + + # 删除帖子本身 + super().delete(*args, **kwargs) + + +class Image(models.Model): + post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='imgs') + imagePath = models.CharField(max_length=256, verbose_name='帖子图片') + + +class Comment(models.Model): + """ 评论表 """ + post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments') + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments') + content = models.TextField(max_length=3000, verbose_name='评论', null=False) + created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') + parent_comment = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies') diff --git a/Server01/static/img/avatar/defaultAvatar.jpg b/Server01/static/img/avatar/defaultAvatar.jpg new file mode 100644 index 0000000..e670cbb Binary files /dev/null and b/Server01/static/img/avatar/defaultAvatar.jpg differ diff --git a/Server01/static/img/post/10-01.jpg b/Server01/static/img/post/10-01.jpg new file mode 100644 index 0000000..1ef271c Binary files /dev/null and b/Server01/static/img/post/10-01.jpg differ diff --git a/Server01/static/img/post/10-02.jpg b/Server01/static/img/post/10-02.jpg new file mode 100644 index 0000000..b5e7bfd Binary files /dev/null and b/Server01/static/img/post/10-02.jpg differ diff --git a/Server01/static/img/post/10-03.gif b/Server01/static/img/post/10-03.gif new file mode 100644 index 0000000..142c7d7 Binary files /dev/null and b/Server01/static/img/post/10-03.gif differ diff --git "a/Server01/static/img/post/14-\351\207\221\346\231\272\347\247\200.jpg" "b/Server01/static/img/post/14-\351\207\221\346\231\272\347\247\200.jpg" new file mode 100644 index 0000000..81c2c29 Binary files /dev/null and "b/Server01/static/img/post/14-\351\207\221\346\231\272\347\247\200.jpg" differ diff --git "a/Server01/static/img/post/15-\346\234\264\345\275\251\350\213\261.jpg" "b/Server01/static/img/post/15-\346\234\264\345\275\251\350\213\261.jpg" new file mode 100644 index 0000000..bbe2e74 Binary files /dev/null and "b/Server01/static/img/post/15-\346\234\264\345\275\251\350\213\261.jpg" differ diff --git "a/Server01/static/img/post/16-\351\207\221\347\217\215\345\246\256.jpg" "b/Server01/static/img/post/16-\351\207\221\347\217\215\345\246\256.jpg" new file mode 100644 index 0000000..8b0f144 Binary files /dev/null and "b/Server01/static/img/post/16-\351\207\221\347\217\215\345\246\256.jpg" differ diff --git a/Server01/static/img/post/17-lisa.jpg b/Server01/static/img/post/17-lisa.jpg new file mode 100644 index 0000000..4908391 Binary files /dev/null and b/Server01/static/img/post/17-lisa.jpg differ diff --git a/Server01/static/img/post/18-html_table.jpg b/Server01/static/img/post/18-html_table.jpg new file mode 100644 index 0000000..1314bd3 Binary files /dev/null and b/Server01/static/img/post/18-html_table.jpg differ diff --git a/Server01/static/img/post/19-ikun.jpg b/Server01/static/img/post/19-ikun.jpg new file mode 100644 index 0000000..0ff1b86 Binary files /dev/null and b/Server01/static/img/post/19-ikun.jpg differ diff --git a/Server01/static/img/post/20-06.jpg b/Server01/static/img/post/20-06.jpg new file mode 100644 index 0000000..faf8ca8 Binary files /dev/null and b/Server01/static/img/post/20-06.jpg differ diff --git a/Server01/static/img/post/21-05.png b/Server01/static/img/post/21-05.png new file mode 100644 index 0000000..1bbc77a Binary files /dev/null and b/Server01/static/img/post/21-05.png differ diff --git a/Server01/static/img/post/22-img1.jpg b/Server01/static/img/post/22-img1.jpg new file mode 100644 index 0000000..d7e47b3 Binary files /dev/null and b/Server01/static/img/post/22-img1.jpg differ diff --git a/Server01/static/img/post/23-img4.jpg b/Server01/static/img/post/23-img4.jpg new file mode 100644 index 0000000..a7a0d2d Binary files /dev/null and b/Server01/static/img/post/23-img4.jpg differ diff --git a/Server01/static/img/post/24-img3.jpg b/Server01/static/img/post/24-img3.jpg new file mode 100644 index 0000000..4163639 Binary files /dev/null and b/Server01/static/img/post/24-img3.jpg differ diff --git a/Server01/static/img/post/25-project.png b/Server01/static/img/post/25-project.png new file mode 100644 index 0000000..7eadfc8 Binary files /dev/null and b/Server01/static/img/post/25-project.png differ diff --git a/Server01/static/img/post/26-user.jpg b/Server01/static/img/post/26-user.jpg new file mode 100644 index 0000000..ce27717 Binary files /dev/null and b/Server01/static/img/post/26-user.jpg differ diff --git a/Server01/static/img/post/27-img.jpg b/Server01/static/img/post/27-img.jpg new file mode 100644 index 0000000..712360c Binary files /dev/null and b/Server01/static/img/post/27-img.jpg differ diff --git a/Server01/tests.py b/Server01/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Server01/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Server01/util/__pycache__/verifyJWT.cpython-39.pyc b/Server01/util/__pycache__/verifyJWT.cpython-39.pyc new file mode 100644 index 0000000..2ff660d Binary files /dev/null and b/Server01/util/__pycache__/verifyJWT.cpython-39.pyc differ diff --git a/Server01/util/verifyJWT.py b/Server01/util/verifyJWT.py new file mode 100644 index 0000000..3db32e7 --- /dev/null +++ b/Server01/util/verifyJWT.py @@ -0,0 +1,51 @@ +import datetime + +import jwt +from django.http import JsonResponse +from jwt import exceptions + +import Server01.models as models +from webServer.settings import SECRET_KEY + + +def authenticate_request(view_func): + def wrapper(request, *args, **kwargs): + # 从请求中获取 JWT 令牌 + try: + token = request.headers.get('Authorization').split(' ')[1] + verify_payload = jwt.decode(token, SECRET_KEY, ['HS256'], verify=True) + # 检查数据库是否存在该用户 + if models.User.objects.filter(username=verify_payload.get('username'), + id=verify_payload.get('user_id')).exists(): + return view_func(request, verify_payload, *args, **kwargs) + return JsonResponse({'error': '未授权访问'}, status=401) + except exceptions.ExpiredSignatureError: + error_message = {'error': '登录身份过期'} + return JsonResponse(error_message, status=401) + except jwt.DecodeError: + error_message = {'error': 'jwt认证失败'} + return JsonResponse(error_message, status=401) + except jwt.InvalidTokenError: + error_message = {'error': '非法的token'} + return JsonResponse(error_message, status=401) + except AttributeError: + error_message = {'error': '非法的访问'} + return JsonResponse(error_message, status=401) + + return wrapper + + +def create_token(user): + # 构造头部 + headers = { + 'typ': 'jwt', + 'alg': 'HS256', + } + # 构造payload + payload = { + 'user_id': user.id, + 'username': user.username, + 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30) # 设置过期时间 + } + result = jwt.encode(payload=payload, key=SECRET_KEY, algorithm='HS256', headers=headers) + return result diff --git a/Server01/views/__pycache__/post.cpython-39.pyc b/Server01/views/__pycache__/post.cpython-39.pyc new file mode 100644 index 0000000..ff74c45 Binary files /dev/null and b/Server01/views/__pycache__/post.cpython-39.pyc differ diff --git a/Server01/views/__pycache__/user.cpython-39.pyc b/Server01/views/__pycache__/user.cpython-39.pyc new file mode 100644 index 0000000..10ea309 Binary files /dev/null and b/Server01/views/__pycache__/user.cpython-39.pyc differ diff --git a/Server01/views/comment.py b/Server01/views/comment.py new file mode 100644 index 0000000..e69de29 diff --git a/Server01/views/post.py b/Server01/views/post.py new file mode 100644 index 0000000..b1f355b --- /dev/null +++ b/Server01/views/post.py @@ -0,0 +1,92 @@ +import json + +from django.http import JsonResponse + +import Server01.models as models +from Server01.util.verifyJWT import authenticate_request + +system = 'D:/vue' + + +def upload_post(request): + file = request.FILES['file'] + id = request.POST.get('id') + file_path = system + '/webServer/Server01/static/img/post/' + str(id) + '-' + file.name + print(id, file_path) + with open(file_path, 'wb') as destination: + for chunk in file.chunks(): + destination.write(chunk) + result = { + 'filename': file.name, + 'filepath': 'http://localhost:8000/static/img/post/' + str(id) + '-' + file.name, + } + post = models.Post.objects.filter(id=id).first() + if post: + models.Image.objects.create(imagePath=result['filepath'], post=post) + return JsonResponse({'data': 'success'}, status=200) + return JsonResponse({'error': '错误的操作'}, status=401) + + +@authenticate_request +def upload_post_info(request, payload): + data = json.loads(request.body) + post = models.Post.objects.create( + title=data.get('title'), + content=data.get('content'), + user_id=data.get('user_id') + ) + return JsonResponse({'data': 'success', 'info': post.id}, status=200) + + +def get_post_detail(request): + data = json.loads(request.body) + id = data.get('id') + post = models.Post.objects.filter(id=id).first() + if post: + imgs = post.imgs.all() + info = { + 'title': post.title, + 'id': post.id, + 'imgs': [img.imagePath for img in imgs], + 'comment': [], + 'user': { + 'id': post.user.id, + 'username': post.user.username, + 'avatar': post.user.avatar + }, + 'createTime': post.created_at + } + return JsonResponse({'info': info}, status=200) + return JsonResponse({'error': '错误的访问'}, status=401) + + +def query_post_index(request): + data = json.loads(request.body) + offset = data['offset'] + limit = 20 # 每页显示的帖子数量 + posts = models.Post.objects.all() + count = posts.count() + + if 0 <= offset < count: + start = offset + end = offset + limit + posts = posts.order_by('-id')[start:end] + return JsonResponse({'info': list(combine_index_post(posts))}, status=200) + + return JsonResponse({'info': []}, status=200) + + +def combine_index_post(posts): + for post in posts: + imgs = post.imgs.all() + info = { + 'title': post.title, + 'id': post.id, + 'img': imgs[0].imagePath, + 'user': { + 'id': post.user.id, + 'username': post.user.username, + 'avatar': post.user.avatar + } + } + yield info diff --git a/Server01/views/user.py b/Server01/views/user.py new file mode 100644 index 0000000..c53f640 --- /dev/null +++ b/Server01/views/user.py @@ -0,0 +1,83 @@ +import json + +from django.http import JsonResponse + +import Server01.models as models +from Server01.util.verifyJWT import create_token + + +# 用户登录 +def login(request): + data = json.loads(request.body) + user = models.User.objects.filter(**data).first() + if user: + token = create_token(user) + user = { + 'id': user.id, + 'username': user.username, + 'avatar': user.avatar, + 'signature': user.signature, + 'token': token + } + return JsonResponse(user, status=200) + error_message = {'error': '邮箱或密码错误'} + return JsonResponse(error_message, status=401) + + +# 用户注册 +def register(request): + data = json.loads(request.body) + email = data['email'] + if check_email(email): + return JsonResponse({'error': '该邮箱已被注册'}, status=401) + try: + models.User.objects.create(**data) + return JsonResponse({'username': data}) + except Exception as e: + print(e) + return JsonResponse({'error': '创建用户失败'}, status=401) + + +def query_user_index(request): + data = json.loads(request.body) + if data.get('id'): + user = models.User.objects.filter(id=data.get('id')).first() + if user: + author = { + 'id': user.id, + 'username': user.username, + 'avatar': user.avatar, + 'signature': user.signature, + 'fans': user.beFocusOn.count(), + 'focusOn': user.focusOn.count(), + 'postsCount': user.posts.count(), + } + info = { + 'user': author, + 'posts': list(combine_index_post(user.posts.all())), + 'collected': list(combine_index_post(user.collected.all())), + 'favorites': list(combine_index_post(user.favorites.all())) + } + return JsonResponse({'data': info}, status=200) + return JsonResponse({'error': '错误的访问'}, status=401) + return JsonResponse({'error': '非法访问'}, status=401) + + +def combine_index_post(posts): + for post in posts: + imgs = post.imgs.all() + info = { + 'title': post.title, + 'id': post.id, + 'img': imgs[0].imagePath, + 'user': { + 'id': post.user.id, + 'username': post.user.username, + 'avatar': post.user.avatar + } + } + yield info + + +def check_email(email): + return models.User.objects.filter(email=email).exists() diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..c432a5c --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webServer.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/webServer/__init__.py b/webServer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/webServer/__pycache__/__init__.cpython-39.pyc b/webServer/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..23fa3d6 Binary files /dev/null and b/webServer/__pycache__/__init__.cpython-39.pyc differ diff --git a/webServer/__pycache__/settings.cpython-39.pyc b/webServer/__pycache__/settings.cpython-39.pyc new file mode 100644 index 0000000..d7e36ee Binary files /dev/null and b/webServer/__pycache__/settings.cpython-39.pyc differ diff --git a/webServer/__pycache__/urls.cpython-39.pyc b/webServer/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000..f52e81c Binary files /dev/null and b/webServer/__pycache__/urls.cpython-39.pyc differ diff --git a/webServer/__pycache__/wsgi.cpython-39.pyc b/webServer/__pycache__/wsgi.cpython-39.pyc new file mode 100644 index 0000000..28a89cc Binary files /dev/null and b/webServer/__pycache__/wsgi.cpython-39.pyc differ diff --git a/webServer/asgi.py b/webServer/asgi.py new file mode 100644 index 0000000..e891c8a --- /dev/null +++ b/webServer/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for webServer project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webServer.settings") + +application = get_asgi_application() diff --git a/webServer/settings.py b/webServer/settings.py new file mode 100644 index 0000000..66b53c9 --- /dev/null +++ b/webServer/settings.py @@ -0,0 +1,148 @@ +""" +Django settings for webServer project. + +Generated by 'django-admin startproject' using Django 4.1. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.1/ref/settings/ +""" +from datetime import timedelta +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = "django-insecure-h)k+5=#(nkfv3o^-o5+_at807f#kf4_l_e(#u8-3%av)4%xz$3" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + +# Application definition + +INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "Server01.apps.Server01Config", + "corsheaders", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + # "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + 'corsheaders.middleware.CorsMiddleware', +] + +ROOT_URLCONF = "webServer.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [] + , + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "webServer.wsgi.application" + +# Database +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'server01', + 'USER': 'root', + 'PASSWORD': '!d0x9sDXS', + 'HOST': '113.125.109.60', + 'PORT': '3306', + } +} + +# Password validation +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] + +# Internationalization +# https://docs.djangoproject.com/en/4.1/topics/i18n/ + +LANGUAGE_CODE = "zh-hans" + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_TZ = True + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + +STATIC_URL = "static/" + +# Default primary key field type +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +CORS_ALLOWED_ORIGINS = [ + 'http://localhost:5173', +] + +CORS_ALLOWED_METHODS = [ + 'GET', + 'POST', + 'OPTIONS', +] + +CORS_ALLOWED_HEADERS = [ + 'Content-Type', +] + +# 启用 CSRF 保护 +CSRF_COOKIE_HTTPONLY = True + + + + + + diff --git a/webServer/urls.py b/webServer/urls.py new file mode 100644 index 0000000..ec18032 --- /dev/null +++ b/webServer/urls.py @@ -0,0 +1,29 @@ +"""webServer URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path +from Server01.views import user, post + +urlpatterns = [ + path("admin/", admin.site.urls), + path("login/", user.login), + path('register/', user.register), + path('index/', user.query_user_index), + path('upload/', post.upload_post), + path('upload/info/', post.upload_post_info), + path('post/detail/', post.get_post_detail), + path('post/', post.query_post_index) +] diff --git a/webServer/wsgi.py b/webServer/wsgi.py new file mode 100644 index 0000000..aa03ff8 --- /dev/null +++ b/webServer/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for webServer project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webServer.settings") + +application = get_wsgi_application()