设计一个微博网页,包括前端后台,用户能够注册登陆,同时发微博,查看别人的微博,看自己的名片,退出等功能。效果如下:
(1)注册登陆界面
(2) 进去之后查看微博(包括评论发表日期等)
(3)自己发微博
(3)自己的名片,个人信息
(4)退出之后返回主页面
步骤:
1. 安装django ,验证在命令行 cmd: import django; django.get_version();
2. django-admin startproject <Project Name>
目录中会出现manage.py文件
3. python manage.py startapp <APP Name>
4. python manage.py runserver 80
5. 在你的<APP>目录下建立文件夹/static/ 用于存放静态文件,建立/templates/用于存放js,bootstrap,img等。
6. 我们在<Project>目录,或者根目录下,找到setting.py文件,在INSTALLED_APP 中添加APP,(注意逗号)。在TEMPLATES的DIRS添加模板路径,'DIR':['/templates/']. 其他地方不变。
在html文件可以直接调用'/static/xx.img'或者'/static/js/jquery-1.11.2.min.js',效果如下:
7. 在<APP>目录下views.py添加函数,比如
def home(request):
return render(request,"homepage.html")
来进行网页与后台交互(渲染)
8. 最后在<Project>目录下找到url.py。在utlpattern中添加 from <APP> import views.home
path('',home) (注意是函数名,不加括号)
如何完成html与views.py的交互。在views.py的函数中添加字典user,并且在render函数中添加参数{"ref":user}。在html中用{{user.XX}}来引用,比如:
def show_user(request):
customer1 = { 'Name': 'Bruce Lee',
'motto': "HuHuHaHi",
'email': 'HUHUHAHI@bruce.lee',
'region': 'Kyoto, Japan',
'avatar': 'Po2.jpg'
}
return render(request,"user.html",{"user":customer1})
<h1 style="font-size:70px">{{user.name}}</h1>
9. 编写models orm数据存储模块,比如我们建立一个1对1的表Wechatuser,再建立一个1对N的表Status,它们都必须继承models.Model. CASCADE表示相关联的表会被一起删除。
from django.contrib.auth.models import User
class Wechatuser(models.Model):
user = models.OneToOneField(User,models.CASCADE)#del
motto = models.CharField(max_length = 100, null=True, blank = True)
image = models.CharField(max_length=50, null=True, blank=True)#最大字符长度50,允许为空
region = models.CharField(max_length=60, null=True, blank=True)
def __str__(self):
return self.user.username #以用户名字为唯一标识符
class Status(models.Model):
user = models.ForeignKey(Wechatuser,models.CASCADE)
webot = models.CharField(max_length = 280)
pics = models.CharField(max_length=100, null=True, blank=True)
time = models.DateTimeField(auto_now_add = True)
def __str__(self):
return self.webot
class Meta:
ordering = ["id"]
如果改为-id就是逆序,接着python manage.py makemigrations进行代码移植
Migrations for 'moments':
moments\migrations\0001_initial.py
- Create model Wechatuser
- Create model Status
这个0001_initial.py就是python版sql语言。
接着python manage.py migrate
10. ok 接下来我们需要管理数据库 <DB>为数据库名
在<APP>下有个admin.py,我们将自己的表进行“注册”
admin.site.register(<DB>)
11. 创建超级管理员进行管理
python manage.py createsuperuser 按照提示操作
12. 在views.py文件
status = <DB>.objects.all()访问所有数据库对象
python断点调试
import pdb
pdb.set_trace() 在作用域内访问各种变量
在html中对某个block,想让它一个接一个展示(假设传入的字典名字为status):
{%for s in status%}
{%endfor%}
{%if status.pics%}
登录模块
from django.contrib.auth.views import LoginView, LogoutView
path('',LoginView.as_view(template_name="homepage.html")),
path('exit',LogoutView.as_view(next_page="/")),
对于登录模块,<form>加入method=“post”
为了防止跨域攻击,在下面加入一句话 {%csrf_token%}
为了避免退出登录后还能进入原来界面,from django.contrib.auth.decorators import login_required
在views.py相关函数前加入一句@login_required
def submit_post(request):
user= Wechatuser.objects.get(user=request.user)
text= request.POST.get("text")
upload_file = request.FILES.get("pics")
# import pdb; pdb.set_trace()
if upload_file:
name = upload_file.name
with open("./moments/static/image/{}".format(name),'wb') as handler:
for chunk in upload_file.chunks():
handler.write(chunk)
else:
name = ""
if text:
status = Status(user=user,webot=text,pics=name)
status.save()
return redirect("/status")
return render(request,"my_post.html")
上述代码能够获取用户在页面POST的信息,并加入到status网页中。
实现用户注册功能
1. 创建用户 user = User(name="",email="")
user.set_password("")
user.save()
User.objects.create(user="",email="")
json.dump()
json.load()
2. 在views.py写register函数
注意抛出错误,返回是以JSON的形式 Javascript Object Notation专门针对JS对象。类似字典
def register(request):
username,email,password = [request.POST.get(k) for k in ("username","email","password")]
try:
user = User(username=username, email=email)
user.set_password(password)
user.save()
Wechatuser.objects.create(user=user)
except Exception as err:
message = str(err)
result = False
else:
message = "Register OK"
result = True
return JsonResponse({"message":message,"result":result})
3.自己写post测试
import requests
data = {
"username":"Hacker",
"password":"YOUAREHACKED",
"email":"hacker@wiki.xyz",
"csrfmiddlewaretoken":"vnb6x6Py5aq0gqbfJKf3GG1qLafpQ6rgiRYHA5cYP192jNFADXPwft0QLCUccMgw",
}
cookies= {"csrftoken":"p0WgAJyd9B5EbKkLlPu56cSPp8P1ZU0NcuJRDIVDTsOGe7O6f24yFZRfpAuOlAP3",
}
r = requests.post("http://localhost/register",data=data,cookies = cookies)
print(r.text)
4.jQuery:
$("#register_name")获取用户输入 其中#表示一个选择器,id="register_name",不带#, 如果要选择一个类class就是$(".register_name")
表示标签,如input。 如果我们想获取标签input中的name属性
#("input[name]").val()即可
使用ajax异步请求获得客户的注册信息:
<script>
function register(){
$.ajax({
url:"/register",
type:"post",
data:{
"username":$("#register_name").val(),
"email":$("#register_email").val(),
"password":$("#register_password").val(),
"csrfmiddlewaretoken":$("input[name='csrfmiddlewaretoken']").val(),
},
success: function(response){
alert(response["message"])};
location.reload();
})
}
$("#register_submit").click(function(){
register()
})
</script>
注意的是,为了安全性,需要进行csrf校验,在表单下如果有{% csrf_token%} 则会自动转换为input标签,我们通过$("input[name=csrfmiddlewaretoken]")就可以查到它。可以F12去在网页上找到。 一般地,自己写个py,还需要cookies,在Chrome的application标签可以找到。 这里的location.reload()保证客户刷新网页之后,之前填写表单会刷新。若注册成功则会弹出对话框。
button标签改为a标签,移去type="submit"属性
接下来实现用户可以更改自己的名片功能.
1.首先要做的就是利用jQuery实现我们想要的功能: 调用replaceWith方法$("#name").replaceWith("<input>")还需要添加style属性,我们可以利用attr("style")来获取原来的样式,把字体改成灰色即可。同时 id , placeholder, value均可以更改。可以用.html()获取value,注意,标签<>内的赋值是用单引号,而单引号内必须为字符串,所以如果用了jQuery函数,必须加双引号来变为字符串。同python可以用“+”实现字符串拼接。有一些使用split来实现分割,trim去除前后空格。
实现简易评论功能
我们现在需要实现简易的评论功能,按照一般的开发步骤,我们先在views.py撰写函数,用于接收前端发送的数据,然后再 在urls.py加入路径-函数链接,再写前端交互。 这里我们需要用到一个最受欢迎的框架bootstrap。https://v3.bootcss.com/。相信我,你一定会爱上它。我们希望在点击按钮时,出现一个弹出框,里面有图标可以点击如下图所示。
因此需要把 bootstrap弹出框相关代码拷入你的html。
<button type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="left" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on 左侧
</button>
同时这儿有一些技巧:
我们要将data-html设为true来使得data-content里的标签代码能够发挥作用。data-后面的是参量。通过class标签来改变图标样式
<button style="float:right;background-color:rgb(51,51,51)"
type="button"
class="btn btn-default"
data-html= "true"
data-toggle="popover"
data-placement="left"
data-content="<span class ='like' style= 'cursor:pointer;font-size:20px' onclick='like({{status.id}})'>
<span style='font-size:20px' class='glyphicon glyphicon-heart' aria-hidden='true'>
</span> Like</span> |
<span class ='comment' style= 'cursor:pointer;font-size:20px' onclick='comment({{status.id}})'><span style='font-size:20px' class='glyphicon glyphicon-comment' aria-hidden='true'>
</span> Comment</span>">
<span class="glyphicon glyphicon-option-horizontal" aria-hidden="true" style="color:white">
</span></button>
在js里面实现对应的交互,只需要按照bootstrap网站提示来就行了:
$(function () {
$('[data-toggle="popover"]').popover()
})
之后是点击功能,要想把鼠标变为手指,我们只需要在style里加cursor:pointer属性即可,之后实现点击功能,οnclick="like()"我们先实现相对容易的点赞:
function like(status_id){
$.ajax({
url:"/like",
type:"post",
data:{
"status_id": status_id,
"csrfmiddlewaretoken":'{{csrf_token}}',
},
success: function(){
//alert("You Like it !")
location.reload()
},
})
}
用ajax一步发送数据,注意csrf_token也要发送,如果成功将页面刷新。
评论评论功能的话,我们需要知道@谁,以及模态框用于用户打字。效果如下:
很棒的是,bootstrap为我们提供了相应Javascript插件:
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
我们将。。。标签更改为<textarea>标签即可,可以,如果想要一点酷炫效果,加入form-control: <textarea id="input" class="form-control" rows="3"></textarea>
在js操作模态框弹出方法是:
$('#myModal').on('shown.bs.modal', function () {
$('#myInput').focus()
})
如何实现搜索功能
如果搜索框内有关键字keyword,我们在数据库调取相应数据,返回给前端界面。如果keyword='' ,那么显示所有条目。
if not keyword:
statuses = Status.objects.all()#show all the status
else:
statuses = Status.objects.filter(user__user__username__contains=keyword) #show targeted status
我们要从数据库get数据,之后渲染到界面上,和之前登陆用的POST相反,我们需要用的是GET方法。
这儿有个{%block ...%}方法,允许我们在不同的html里调用某个属性,比如我们在base.html里面写了一个搜索框如下
<input type="text" name="keyword" class="form-control" placeholder="Look for ..." {% block searchbar %}{%endblock%}/>
我们要将keyword作为一个关键字,运用GET方法,在数据库调取符合要求的数据。
后面的searchbar作为一个block,其它的界面会继承base.html,所以在status.html页面对searchbar进行定义:
{% block searchbar %}value="{{keyword}}"{% endblock %}
但是笔者在再次查询为空字符时遇到问题