BBS前后端混合项目--01

总路由

# urls.py
"""BBS1 URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views1. Add an import:  from my_app import views2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views1. Add an import:  from other_app.views import Home2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf1. Import the include() function: from django.urls import include, path2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
from django.views.static import serve
from django.conf import settingsurlpatterns = [path('admin/', admin.site.urls),path('register/', views.register),path('check_username/', views.check_username),path('login/', views.login),path('logout/', views.logout),path('get_code/', views.get_code),path('upanddown/', views.upanddown),path('commit/', views.commit),path('backend/', views.backend),path('', views.home),path('change_password/', views.change_password),path('add_article/', views.add_article),path('delete/<int:pk>', views.delete_article),path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT}),re_path('(?P<username>\w+)/(?P<choice>category|tag|archive)/(?P<condition>.*?).html', views.site),path('<str:username>/articles/<int:article_id>.html', views.article_detail),path('<str:username>', views.site),  # 个人站点路由放最后---》上面所有都匹配完了--->再看是不是个人站点
]

总配置

# settings
from pathlib import Path
import osBASE_DIR = Path(__file__).resolve().parent.parentSECRET_KEY = 'django-insecure-s7$a4504xk&4-3zdd^1s50f^_%^_vjj_i-beq=b--r-pw%rptz'DEBUG = TrueALLOWED_HOSTS = []INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app01.apps.App01Config',
]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',
]ROOT_URLCONF = 'BBS1.urls'TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR,'templates')],'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 = 'BBS1.wsgi.application'# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': BASE_DIR / 'db.sqlite3',
#     }
# }
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'bbs1','USER': 'root','PASSWORD': 'JIAJIA','HOST': '127.0.0.1','PORT': 3306}
}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',},
]# 国际化
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = FalseSTATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'AUTH_USER_MODEL='app01.UserInfo'

总模版层

# views.py
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from .forms import RegisterForm
from .models import UserInfo, Article, Category, Tag, UpAndDown, Commit
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
from .utills import get_random_code, get_random_rgb
import random, json
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.db.models import F
from django.db import transaction# Create your views here.def register(request):if request.method == 'GET':form = RegisterForm()return render(request, 'register.html', {'form': form})else:# # 1 数据# print(request.POST)# # 2 文件# print(request.FILES.get('my_img'))# 取出头像avatar = request.FILES.get('my_img')# 校验数据是否合法'''username: adminpassword: 123email: 306334678@qq.comphone: 17717823244avatar:文件'''print(request.POST.get('username'))form = RegisterForm(request.POST)# 使用form校验传入的数据print(form)print(form.is_valid())if form.is_valid():  # 校验通过# 保存data = form.cleaned_data# 把re_password 弹出data.pop('re_password')# 把头像加入if avatar:data['avatar'] = avatarUserInfo.objects.create_user(**data)return JsonResponse({'code': 100, 'msg': '注册成功'})else:return JsonResponse({'code': 101, 'msg': '注册失败', 'errors': form.errors})# 校验用户名是否存在接口
def check_username(request):username = request.GET.get('username')res = UserInfo.objects.filter(username=username).exists()if res:return JsonResponse({'code': 100, 'msg': '用户已经存在'})else:return JsonResponse({'code': 101, 'msg': '您可以注册'})def login(request):if request.method == 'GET':return render(request, 'login.html')else:username = request.POST.get('username')password = request.POST.get('password')net_code = request.POST.get('code').lower()#code = request.POST.get('code').lower()  # 会存在bug# 1 校验验证码,取出老验证码,忽略大小写old_code = request.session.get('code').lower()if code == old_code:# 2 去验证用户了---》# 你们去实现:先根据用户名查出用户,check_password校验密码# UserInfo.objects.filter(username=username,password=password).exists() # 错的user = authenticate(username=username, password=password)if user:# 登录成功--->内部写session了auth_login(request, user)return JsonResponse({'code': 100, 'msg': '登录成功', 'url': '/'})else:return JsonResponse({'code': 101, 'msg': '用户名或密码错误'})else:return JsonResponse({'code': 102, 'msg': '验证码错误'})def logout(request):auth_logout(request)return redirect('/')def home(request):article_list = Article.objects.all().order_by('create_time')return render(request, 'home.html', locals())def get_code(request):height = 38width = 300image_tmp = Image.new('RGB', (300, 38), (255, 255, 255))# 把空图片放在了画板上,就可以写字了draw = ImageDraw.Draw(image_tmp)# 加入字体# img_font = ImageFont.truetype('./static/font/xgdl.ttf', 23)   # 字体,字体大小写img_font = ImageFont.truetype('./static/font/ss.TTF', 23)# 验证码code_str = get_random_code()print(code_str)# 重要,要保存request.session['code'] = code_strfor i, item in enumerate(code_str):draw.text((30 + i * 50, 3), item, fill=get_random_rgb(), font=img_font)  # (x轴,y轴),字,字颜色,字体# 增加难度--->在图片上画点for i in range(30):draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_rgb())# 画弧形x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_rgb())# 在图片上划线for i in range(3):x1 = random.randint(0, width)x2 = random.randint(0, height)y1 = random.randint(0, width)y2 = random.randint(0, height)draw.line((x1, y1, x2, y2), fill=get_random_rgb())# 放在内存中,一旦不用,自动清理内存my_io = BytesIO()image_tmp.save(my_io, 'png')return HttpResponse(my_io.getvalue())def site(request, username,**kwargs):user = UserInfo.objects.filter(username=username).first()if user:# 查出当前用户,所有的文章article_list = Article.objects.filter(blog_id=user.blog.id).all()choice = kwargs.get('choice', None)condition = kwargs.get('condition', None)  # 如果 choice 有值,condition一定有if choice and choice == 'category':# choice有值 说明不是个人站点的:可能是 tag筛选,标签筛选,日期筛选,并且choice是 category,按标签过滤的category_name = Category.objects.filter(pk=condition).first().namearticle_list = article_list.filter(category_id=condition)elif choice and choice == 'tag':tag_name = Tag.objects.filter(pk=condition).first().namearticle_list = article_list.filter(tag__id=condition)elif choice and choice == 'archive':date_y_m = conditionyear, month = condition.split('-')article_list = article_list.filter(create_time__year=year, create_time__month=month)return render(request, 'site.html', locals())else:return render(request, '404.html')def article_detail(request,username,article_id):article = Article.objects.filter(pk=article_id).first()commit_list = Commit.objects.filter(article_id=article_id)return render(request,'article_detail.html',locals())# 加装饰器的话,无法制定返回给agax的数据,前端不好操作
def upanddown(request):# 当前登录用户,如果取不出来,需要返回让它登录user = request.userif user.is_authenticated:article_id = request.POST.get('article_id')up_or_down = request.POST.get('up')  # 是字符串类型,转成 布尔up_or_down = json.loads(up_or_down)  # ajax传入的是二进制res = UpAndDown.objects.filter(article_id=article_id, user=user).first()if res:return JsonResponse({'code': 102, 'msg': '您已经点过了'})else:# 存点赞点踩记录,记录被点的文章,下次查,若文章在数据库,说明点过了UpAndDown.objects.create(user=user, article_id=article_id, is_up=up_or_down)if up_or_down:Article.objects.filter(pk=article_id).update(up_number=F('up_number') + 1)return JsonResponse({'code': 100, 'msg': '点赞成功'})else:Article.objects.filter(pk=article_id).update(down_number=F('down_number') + 1)return JsonResponse({'code': 100, 'msg': '点踩成功'})else:return JsonResponse({'code': 101, 'msg': '您没有登录,请先 <a href="/login/" style="color: red">登录</a>'})# 评论
def commit(request):user = request.userif user.is_authenticated:article_id = request.POST.get('article_id')content = request.POST.get('content')with transaction.atomic():  # 开启事务dcommit=Commit.objects.create(user=user, article_id=article_id, content=content)# 评论数加一Article.objects.filter(pk=article_id).update(commit_number=F('commit_number')+1)return JsonResponse({'code': '100', 'msg': '评论成功', 'content':commit.content , 'username': user.username})else:return JsonResponse({'code': '101', 'msg': '没有登录'})@login_required(login_url='/login/')
def backend(request):article_list = Article.objects.filter(blog=request.user.blog)return render(request,'backend.html',locals())@login_required(login_url='/login/')
def delete_article(request,pk):Article.objects.filter(pk=pk).delete()return redirect('/backend/')@login_required(login_url='/login/')
def add_article(request):if request.method == 'GET':# 当前作者所有分类category_list = Category.objects.filter(blog=request.user.blog).all()tag_list = Tag.objects.filter(blog=request.user.blog).all()return render(request, 'add_article.html',locals())else:title = request.POST.get('title')content = request.POST.get('content')category = request.POST.get('category')desc = content[0:30]tag = request.POST.getlist('tag')# 加入数据库article = Article.objects.create(title=title, desc=desc, content=content, category_id=category,blog=request.user.blog)article.tag.add(*tag)return redirect('/backend/')

总utils-验证码

# utils.py
import random
# 验证码
def get_random_code():code=''for i in range(5):upper_char = chr(random.randint(65,90))low_char = chr(random.randint(97,122))num_char = str(random.randint(0,9))res=random.choice([upper_char,low_char,num_char])code+=resreturn code# 画布
def get_random_rgb():return (random.randint(0,255),random.randint(0,255),random.randint(0,255))if __name__ == '__main__':print(get_random_code())

admin.py

from django.contrib import admin# Register your models here.from .models import *admin.site.register(UserInfo)
admin.site.register(Blog)
admin.site.register(Tag)
admin.site.register(Category)
admin.site.register(Article)
admin.site.register(ArticleToTag)
admin.site.register(Commit)

总数据库表

# models.py
from django.db import models
from django.contrib.auth.models import AbstractUserclass UserInfo(AbstractUser):# 扩写字段---》手机号,头像,phone = models.CharField(max_length=32, verbose_name='手机号', blank=True, null=True)# /media/avatar/default.png# 必须安装pillow 才能使用 ImageFieldavatar = models.ImageField(upload_to='avatar', default='avatar/default.png')blog = models.OneToOneField(to='Blog', on_delete=models.CASCADE, null=True)class Meta:verbose_name_plural = '用户表'  # 给其他人看,知道这是用户表def __str__(self):return self.usernameclass Blog(models.Model):# 博客标题site_title = models.CharField(max_length=32)# 博客副标题site_name = models.CharField(max_length=32)# 博客样式# 每个人样式不同(文件地址)site_style = models.CharField(max_length=32)class Meta:verbose_name_plural = '博客表'def __str__(self):# 会报错try:return self.userinfo.username + '---' + self.site_titleexcept Exception as e:return self.site_titleclass Tag(models.Model):name = models.CharField(max_length=32)blog = models.ForeignKey(to=Blog, on_delete=models.SET_NULL, null=True)class Meta:verbose_name_plural = '标签表'def __str__(self):return self.nameclass Category(models.Model):name = models.CharField(max_length=32)blog = models.ForeignKey(to=Blog, on_delete=models.SET_NULL, null=True)class Meta:verbose_name_plural = '分类表'def __str__(self):return self.nameclass Article(models.Model):title = models.CharField(max_length=128)# 文章摘要desc = models.CharField(max_length=256, verbose_name='文章摘要')# 文章详情  大文本content = models.TextField()create_time = models.DateTimeField(auto_now_add=True)# 关联字段# 标签和分类up_number = models.IntegerField(default=0)down_number = models.IntegerField(default=0)commit_number = models.IntegerField(default=0)# 关联字段# 标签和分类category = models.ForeignKey(to=Category, on_delete=models.SET_NULL, null=True)# 多对多,手动创建中间表tag = models.ManyToManyField(to=Tag, through='ArticleToTag', through_fields=('article', 'tag'))# 博客blog = models.ForeignKey(to=Blog, on_delete=models.CASCADE)class Meta:verbose_name_plural = '文章表'def __str__(self):return self.titleclass ArticleToTag(models.Model):article = models.ForeignKey(to=Article, on_delete=models.CASCADE)tag = models.ForeignKey(to=Tag, on_delete=models.CASCADE)class Meta:verbose_name_plural = '中间表'class UpAndDown(models.Model):user = models.ForeignKey(to=UserInfo, on_delete=models.CASCADE)article = models.ForeignKey(to=Article, on_delete=models.CASCADE)is_up = models.BooleanField(default=True)create_time = models.DateTimeField(auto_now_add=True)# 联合唯一# unique_together=('user','article')class Meta:verbose_name_plural = '点赞点踩'def __str__(self):return self.is_upclass Commit(models.Model):user = models.ForeignKey(to=UserInfo, on_delete=models.CASCADE)article = models.ForeignKey(to=Article, on_delete=models.CASCADE)content = models.CharField(max_length=256)create_time = models.DateTimeField(auto_now_add=True)# 自关联,评论层级---》子评论   一定要写null=Trueparent_id = models.ForeignKey(to='self', on_delete=models.CASCADE, null=True)class Meta:verbose_name_plural = '评论表'def __str__(self):return self.content

asgi.py

import osfrom django.core.asgi import get_asgi_applicationos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'BBS1.settings')application = get_asgi_application()

展示

今日思维导图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/2519.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

related_name和related_query_name属性

在Django模型继承中&#xff0c;假如在外键或多对多字段中使用了related_name属性或related_query_name属性&#xff0c;则必须为该字段提供一个独一无二的反向名字和查询名字。但是&#xff0c;这样在抽象基类中一般会引发问题&#xff0c;因为基类中的字段都被子类继承并且保…

初见-响应式编程-002

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace #Reacti…

BERT-CRF 微调中文 NER 模型

文章目录 数据集模型定义数据集预处理BIO 标签转换自定义Dataset拆分训练、测试集 训练验证、测试指标计算推理其它相关参数CRF 模块 数据集 CLUE-NER数据集&#xff1a;https://github.com/CLUEbenchmark/CLUENER2020/blob/master/pytorch_version/README.md 模型定义 imp…

【iOS开发】(五)react Native路由和导航20240421-22

【iOS开发】(五)react Native 路由和导航Navigation 20240421 在&#xff08;一&#xff09;&#xff08;二&#xff09;中我们 Reactnative搭建了开发环境、学习了 基础语法、状态管理&#xff0c;JSX、组件、状态和生命周期以及样式布局等。 在&#xff08;三&#xff09;&a…

MATLAB 数据类型

MATLAB 数据类型 MATLAB 不需要任何类型声明或维度语句。每当 MATLAB 遇到一个新的变量名&#xff0c;它就创建变量并分配适当的内存空间。 如果变量已经存在&#xff0c;那么MATLAB将用新内容替换原始内容&#xff0c;并在必要时分配新的存储空间。 例如&#xff0c; Tota…

Vue3中使用无缝滚动插件vue3-seamless-scroll

官网&#xff1a;https://www.npmjs.com/package/vue-seamless-scroll 1、实现效果文字描述&#xff1a; 表格中的列数据进行横向无缝滚动&#xff0c;某一列进行筛选的时候&#xff0c;重新请求后端的数据&#xff0c;进行刷新 2、安装&#xff1a;npm i vue3-seamless-scrol…

小程序 rich-text 解析富文本 图片过大时如何自适应?

在微信小程序中&#xff0c;用rich-text 解析后端返回的数据&#xff0c;当图片尺寸太大时&#xff0c;会溢出屏幕&#xff0c;导致横向出现滚动 查看富文本代码 图片是用 <img 标签&#xff0c;所以写个正则匹配一下图片标签&#xff0c;手动加上样式即可 // content 为后…

Python 面向对象——5.多态

本章学习链接如下&#xff1a; Python 面向对象——1.基本概念 Python 面向对象——2.类与对象实例属性补充解释&#xff0c;self的作用等 Python 面向对象——3.实例方法&#xff0c;类方法与静态方法 Python 面向对象——4.继承 1.基本概念 多态是面向对象编程&#x…

贪吃蛇(C语言版)

在我们学习完C语言 和单链表知识点后 我们开始写个贪吃蛇的代码 目标&#xff1a;使用C语言在Windows环境的控制台模拟实现经典小游戏贪吃蛇 贪吃蛇代码实现的基本功能&#xff1a; 地图的绘制 蛇、食物的创建 蛇的状态&#xff08;正常 撞墙 撞到自己 正常退出&#xf…

Python蜘蛛侠

目录 写在前面 蜘蛛侠 编写代码 代码分析 更多精彩 写在后面 写在前面 本期小编给大家推荐一个酷酷的Python蜘蛛侠&#xff0c;一起来看看叭~ 蜘蛛侠 蜘蛛侠&#xff08;Spider-Man&#xff09;是美国漫威漫画宇宙中的一位标志性人物&#xff0c;由传奇创作者斯坦李与艺…

探索ChatGPT在提高人脸识别与软性生物识准确性的表现与可解释性

概述 从GPT-1到GPT-3&#xff0c;OpenAI的模型不断进步&#xff0c;推动了自然语言处理技术的发展。这些模型在处理语言任务方面展现出了强大的能力&#xff0c;包括文本生成、翻译、问答等。 然而&#xff0c;当涉及到面部识别和生物特征估计等任务时&#xff0c;这些基于文…

设计模式-00 设计模式简介之几大原则

设计模式-00 设计模式简介之几大原则 本专栏主要分析自己学习设计模式相关的浅解&#xff0c;并运用modern cpp 来是实现&#xff0c;描述相关设计模式。 通过编写代码&#xff0c;深入理解设计模式精髓&#xff0c;并且很好的帮助自己掌握设计模式&#xff0c;顺便巩固自己的c…

用于车载T-BOX汽车级的RA8900CE

用于车载T-BOX等高精度计时的汽车级时钟模块RTC:RA8900CE.车载实时时钟芯片RA8900CE内置32.768Khz的晶体&#xff0c;实现年、月、日、星期、小时、分钟和秒精准计时。RA8900CE满足AEC-Q200认证&#xff0c;内置温补功能&#xff0c;保证实时时钟的稳定可靠&#xff0c;功耗低至…

【Linux】解决ubuntu20.04版本插入无线网卡没有wifi显示【无线网卡Realtek 8811cu】

ubuntu为Realtek 8811cu安装驱动&#xff0c;解决wifi连接问题 1、确认无线网卡的型号-Realtek 8810cu2、下载并配置驱动 一句话总结&#xff1a;先确定网卡的型号&#xff0c;然后根据网卡的型号区寻找对应的驱动下载&#xff0c;下载完成之后在ubuntu系统中进行编译&#xff…

HTTP慢连接攻击的原理和防范措施

随着互联网的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;网络攻击事件频繁发生。其中&#xff0c;HTTP慢速攻击作为一种隐蔽且高效的攻击方式&#xff0c;近年来逐渐出现的越来越多。 为了防范这些网络攻击&#xff0c;我们需要先了解这些攻击情况&#xff0c;这样…

【笔试】03

FLOPS FLOPS 是 Floating Point Operations Per Second 的缩写&#xff0c;意为每秒浮点运算次数。它是衡量计算机性能的指标&#xff0c;特别是用于衡量计算机每秒能够执行多少浮点运算。在高性能计算领域&#xff0c;FLOPS 被广泛用来评估超级计算机、CPU、GPU 和其他处理器…

2024年区块链链游即将迎来大爆发

随着区块链技术的不断发展和成熟&#xff0c;其应用领域也在不断扩展。其中&#xff0c;区块链链游&#xff08;Blockchain Games&#xff09;作为区块链技术在游戏行业中的应用&#xff0c;备受关注。2024年&#xff0c;区块链链游行业即将迎来爆发&#xff0c;这一趋势不容忽…

Windows10如何关闭Edge浏览器的Copilot

在Windows10更新后&#xff0c;打开Edge浏览器&#xff0c;无论复制什么内容&#xff0c;都会弹出Copilot人工智能插件&#xff0c;非常令人反感&#xff0c;网上搜索的关闭方法都非常麻烦&#xff0c;比如&#xff1a;组策略和注册表。自己摸索得出最简便有效的关闭方法。 1、…

【java毕业设计】 基于Spring Boot+mysql的高校心理教育辅导系统设计与实现(程序源码)-高校心理教育辅导系统

基于Spring Bootmysql的高校心理教育辅导系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring Bootmysql的高校心理教育辅导系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及…

一致性hash

一、什么是一致性hash 普通的hash算法 (hashcode % size )&#xff0c;如果size发生变化&#xff0c;几乎所有的历史数据都需要重hash、移动&#xff0c;代价非常大&#xff0c;常见的java中的hashmap就是如此。 那如果在hash表扩容或者收缩的时候size能够保持不变&#xff0…