***想对列出2个自己遇到的报错***
报错1:OSError: cannot open resource
原因:字体忘记修改
报错2:页面报错
检测后发现是漏一个括号
***所以我总结一个自己的报错解决方法:***
1.主要是看前端控制台和后端编辑器里弹出来的报错代码----目的:观察是否可以定位到错误的那行代码
2.将错误代码复制到csdn、百度、gpt查找原因
3.如果自己解决不了,可以请求大佬帮助
****关于“报错”给自己的建议:***
1.多积累报错的类型
2.细心耐心检查自己的代码(ps:不知道大家会不会经常因为写错一个单词或者一些标点符号的错误我引起的报错。大概这是因为我对代码、语法不熟悉所导致的吧)
***下面我复盘一下django的学习***
1.记录心情:
首先,很开心自己居然可以搭建出一个网站,真是太酷辣~
之前觉得,搭建一个网站应该很麻烦吧,感觉我也好复杂,要前后端、还有数据库什么的,直接给我打退堂鼓了,真正学习后才发现,just so so----------------所以:不知则为难,希望自己以后要勇于挑战勇于尝试、保持好奇!
2.技术复盘:
1)首先是django的搭建和app的创建以及注册
>>>安装Django:
pip install django
>创建Django项目
django-admin startproject (项目名称)
ps:如果用pycharm创建,要将settings.py中的DIR templates删除
>创建app
python manage.py startapp (app名字)
>注册app(否则app下的models.py写类时,无法在数据库中创建表)
INSTALLED_APPS = [ ... "app01.apps.App01Config" ]
>配置 静态文件路径&模板路径(放在app目录下)
STATIC_URL = '/static/' # 添加这段代码 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
>配置数据库相关操作
①第三方模块(django3版本)
pip install mysqlclient
②自己在mysql中创建一个数据库
③配置数据库连接settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'world', # 数据库名字 'USER': 'root', 'PASSWORD': 'root', 'HOST': '127.0.0.1', # 那台机器安装了MySQL 'PORT': 3306, } }
④在app下的models.py中编写数据表
from django.db import models class Admin(models.Model): """管理员""" username =models.CharField(verbose_name="用户名",max_length=32) password=models.CharField(verbose_name="密码",max_length=64) def __str__(self): return self.username class Department(models.Model): """部门表""" title=models.CharField(verbose_name='标题',max_length=32) def __str__(self): return self.title
>制行两个命令:
python manage.py makemigrations
python manage.py migrate
2)启动项目:
在 Terminal 里面输入: python(可以直接写python.exe的所在地址) manage.py runserver
3)在url中创建 路由(URL 和 函数的对应关系)
4)在views.py(视图函数,编写业务逻辑)中创建函数结合前端跳转完成增删改查的操作
①增:
def depart_add(request): """添加部门""" if request.method == "GET": return render(request, 'depart_add.html') # 获取用户提交的数据 depar_title = request.POST.get("title") # 添加到数据库 models.Department.objects.create(title=depar_title) return redirect("/depart/list/")
②删:
"""删除部门""" # 获取用户提交的数据 depar_id = request.GET.get("id") # 删除部门 models.Department.objects.filter(id=depar_id).delete() return redirect("/depart/list/")
③改:
def depart_edit(request, nid): """修改""" if request.method == "GET": # 获取用户提交的数据 # depar_id=request.GET.get("id") # 获取部门信息 depar_info = models.Department.objects.filter(id=nid).first() return render(request, 'depart_edit.html', {'depar_info': depar_info}) # 获取用户修改的数据 depar_title = request.POST.get("title") # 修改到数据库 models.Department.objects.filter(id=nid).update(title=depar_title) return redirect("/depart/list/")
④查:
# data_list = models.PrettyNum.objects.all() # return render(request, 'pretty_list.html', {'data_list': data_list})
5)在templates目录,编写HTML模板(含有模板语法、继承、{% static 'xx' %})
6)复用:写一些常用的方法
①bootstrap.py:继承ModelForm写了自己的BootStrapModelForm样式(在页面中展现自己的字题样式)
②code.py:生成验证码(使用里面所写的check_code方法)
使用方法(在views.py中):
def image_code(request): """生成图片验证码""" img,code_string = check_code() # 将验证码写入session中(以便后续获取验证码再进行校验) request.session['image_code'] = code_string # 给session设置60s超时 request.session.set_expiry(60)
from io import BytesIO stream = BytesIO() img.save(stream, 'png') return HttpResponse(stream.getvalue())
③encrypt.py(md5加密):
import hashlib from django.conf import settings def md5(data_string): obj=hashlib.md5(settings.SECRET_KEY.encode('utf-8')) obj.update(data_string.encode('utf-8')) return obj.hexdigest()
使用:
④form.py:
写ModelForm组件
⑤pagination.py:
封装了分页的功能(具体使用方法在里面有写清楚)
7)注销功能:
def logout(request): """注销""" request.session.clear() # 把当前用户的session清理掉 return redirect("/login/")
8)ModelForm & Form组件,在我们开发增删查改功能
①生成HTML标签(生成默认值)
②请求数据进行校验
> 正则表达式
# 手机号格式校验方式一: mobile = forms.CharField( label="手机号", validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误'), ], )
>钩子方法
def clean_confirm_password(self): pwd = self.cleaned_data.get("password") confirm_pwd = md5(self.cleaned_data.get("confirm_password")) if confirm_pwd != pwd: raise ValidationError("密码不一致") # 返回什么,此字段以后保存到数据库就是什么 return confirm_pwd
③保存到数据库(ModelForm所特有的)
form.save()
④获取错误信息
form.errors
9)Cookie和Session,用户登入信息保存起来
10)中间件,实现用户认证(基于:process_request方法)
11)ORM操作
筛选:models.User.objects.filter(id="xxx")
排序:models.User.objects.filter(id="xxx").oeder_by("-id")
***一些小知识点***
1.如果想往数据库中批量加入信息
# 添加数据(加如10条信息到PrettyNum表中) # for i in range(10): # models.PrettyNum.objects.create(mobile="13850997126",price=100,level=5,status=2)
2.搜索功能
1)后端:
"""靓号列表""" data_dict = {} search_data = request.GET.get('q', "") if search_data: data_dict["mobile__contains"] = search_data
2)前端:
<div class="input-group" style="float:right;width:300px"> <input type="text" name="q" class="form-control" placeholder="Search for..." value="{{search_data}}"> <span class="input-group-btn"> <button class="btn btn-default" type="submit"> <span class="glyphicon glyphicon-search" aria-hidden="true"></span> </button> </span> </div>
3.封装常用的样式和功能(进行灵活复用)
前端封装:类似这样子
我们之后使用:
在{% block content %} {% endbloc %}中增加内容
在{% block js %}{% endblock %}中加入js
ps:如果要加入css也是可以的哦,但是要在前端模板中以同样的方式写入{% block js %}{% endblock %}
***Ajax***
细节:
①给提交按钮设置id(用于绑定Ajax事件)和typy=“button”(如果type=“submit”则为提交表单,这样子页面就会刷新)
html页面:
<script type="text/javascript"> $(function(){ // 页面框架加载完成之后代码自动制行 bindBtnAddEvent(); }) function bindBtnAddEvent(){ $("#btnAdd").click(function(){ <!-- 清空页面数据--> $(".error-msg").empty(); <!--向/task/ajax/发送ajax请求(以post方式)--> $.ajax({ url: "/task/ajax/", type: "post", <!-- 将表单中用户填写的信息全部打包--> data:$("#addForm").serialize(), dataType: "json", success: function (data) { if(data.status){ alert("添加成功"); <!-- 用js实现页面的刷新--> location.reload(); }else{ <!-- 错误信息展示--> $.each(data.error,function(name,data){ <!-- console.log(data.error);--> $("#id_"+name).next().text(data[0]); }) } } }); }); } </script>
views.py:
# 免除csrf认证 @csrf_exempt def task_ajax(request): # print(request.GET) print(request.POST) # 1.用户通过Ajax发过来的数据进行效验(ModelForm进行校验) form = TaskModelForm(data=request.POST) if form.is_valid(): form.save() # 给前端返回一个字典 data_dict={"status":True} return HttpResponse(json.dumps(data_dict)) # return JsonResponse(data_dict) data_dict = {"status": False,'error':form.errors} return HttpResponse(json.dumps(data_dict,ensure_ascii=False))