https://studybuddev.herokuapp.com/
1.新建一个叫base的app 
2.第一个页面
第一个页面
keep
3.view.py 视图函数
4.搞templates模板
参考:
5.有点难理解,继承模板
继承模板,继承'main.html'
6.调用后端数据 传一个字典数据库py
目前是
7.
迁移templates
增加urls 分页
keep on!
2.使用真正的数据库
迁移数据库 : 内置迁移
python manage.py migrate
python manage.py runserver
然后去modes.py 创建我们的数据库表
makemigrations生成ddl(数据库模式定义语言),migrate真正地去执行ddl。执行完makemigrations只是生成了对应的sql语句,还并没真正将改动迁移到数据库中。需要执行migrate才能将改动迁移到数据库,22完成建表、修改字段等操作。
8.Django自带后台127.0.0.1:8000/admin/
http://localhost:8000/admin
jango 内置面板 浏览器输入127.0.0.1:8000/admin/ 即可查看Django自带后台
添加数据
9.message 模块 models
00x: Django models.Model详解-优快云博客
当我们设置 ForeignKey 的时候,有一个 on_delete 参数,主要用于当被关联的外键的数据被删除时,自身数据的处理。
CASCADE 关联删除,App2 的数据被删除时,App1 关联的数据也被删除
PROTECT 保护处理,如果 App2 的数据被 App1 关联,那么关联了的 App2 的数据不会被删除
SET_NULL 置空处理,如果 App2 的数据被删除,App1 中关联了该条被删除的App2的数据这个字段都会被设置为 NULL
DO_NOTHING 不处理,原数据不会有任何操作,也就是说 App2 的某条数据被删除,App1 中的引用还在。
10.模块迁移 message;topic;Room
用django内置模块 user
迁移
在admin面板中注册登记
可以看到
随便添加一些数据
11.前端视图
keep on
创 room表单分页
12.写form表单
一
二:新增功能(createRoom)完后返回home页面,并降序现实room列表。
三:update功能
四:delete功能
13. side bar 侧边栏;搜索框
1.侧边栏
2.搜索框
1)现在地址栏中实现
3.显示当前可用room数量
14.用户登录User login、Message消息框架
Django框架之Message消息框架_django.contrib.messages-优快云博客
2)退出
15.restricted pages受限页面 @login_required装饰器
(写错了 是重定向到 ‘ login ’ 页面)
1)提示user 不能修改别人的Room
2)对user隐藏自不能编辑的 标签Edit,Delete
3)已经登录 不希望用户进入login页面 还要再重新登录
16.用户注册
1)要实现
2)
17.聊天室功能,评论区
1)显示评论区信息
2)发评论
3)many to many关系 (多user----1room,多room----1user)
4)删除评论
18.activity feed 活动摘要
1)最新评论置顶。
2)用户只能删除自己的评论
3)
19.user profile page用户个人资料页面
20.静态文件
1).
2).调整下create页面
3)
21.主题安装(全html)
1.前端文件的插入
2、搜索框
3.使下拉框生效
4.登入登出功能 login logout
5.
5. topic_component,feed_component,activity_component,,,,home.html
feed_component
{% for ro in rooms %}
<div class="roomListRoom">
<div class="roomListRoom__header">
<a href="{% url 'user-profile' ro.host.id %}" class="roomListRoom__author">
<div class="avatar avatar--small">
<img src="https://randomuser.me/api/portraits/women/11.jpg" />
</div>
<span>@{{ ro.host.username }}</span>
</a>
<div class="roomListRoom__actions">
<span>{{ ro.updated|timesince }}</span>
</div>
</div>
<div class="roomListRoom__content">
<a href="/room/{{ ro.id }}">{{ ro.name }}</a>
</div>
<div class="roomListRoom__meta">
<a href="/room/{{ ro.id }}" class="roomListRoom__joined">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>user-group</title>
<path
d="M30.539 20.766c-2.69-1.547-5.75-2.427-8.92-2.662 0.649 0.291 1.303 0.575 1.918 0.928 0.715 0.412 1.288 1.005 1.71 1.694 1.507 0.419 2.956 1.003 4.298 1.774 0.281 0.162 0.456 0.487 0.456 0.85v4.65h-4v2h5c0.553 0 1-0.447 1-1v-5.65c0-1.077-0.56-2.067-1.461-2.584z"
></path>
<path
d="M22.539 20.766c-6.295-3.619-14.783-3.619-21.078 0-0.901 0.519-1.461 1.508-1.461 2.584v5.65c0 0.553 0.447 1 1 1h22c0.553 0 1-0.447 1-1v-5.651c0-1.075-0.56-2.064-1.461-2.583zM22 28h-20v-4.65c0-0.362 0.175-0.688 0.457-0.85 5.691-3.271 13.394-3.271 19.086 0 0.282 0.162 0.457 0.487 0.457 0.849v4.651z"
></path>
<path
d="M19.502 4.047c0.166-0.017 0.33-0.047 0.498-0.047 2.757 0 5 2.243 5 5s-2.243 5-5 5c-0.168 0-0.332-0.030-0.498-0.047-0.424 0.641-0.944 1.204-1.513 1.716 0.651 0.201 1.323 0.331 2.011 0.331 3.859 0 7-3.141 7-7s-3.141-7-7-7c-0.688 0-1.36 0.131-2.011 0.331 0.57 0.512 1.089 1.075 1.513 1.716z"
></path>
<path
d="M12 16c3.859 0 7-3.141 7-7s-3.141-7-7-7c-3.859 0-7 3.141-7 7s3.141 7 7 7zM12 4c2.757 0 5 2.243 5 5s-2.243 5-5 5-5-2.243-5-5c0-2.757 2.243-5 5-5z"
></path>
</svg>
{{ ro.participants.all.count }} Joined
</a>
<p class="roomListRoom__topic">{{ ro.topic.name }}</p>
</div>
</div>
{% endfor %}
topic_cpmponent
<div class="topics__header">
<h2>Browse Topics</h2>
</div>
<ul class="topics__list">
<li>
<a href="{% url 'home' %}" class="active">All <span>{{ topics.count }}</span></a>
</li>
{% for topic in topics %}
<li>
<a href="{% url 'home' %}?q={{ topic.name }}">{{ topic.name }}<span>{{ topic.room_set.all.count }}</span></a>
</li>
{% endfor %}
</ul>
<a class="btn btn--link" href="/">
More
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>chevron-down</title>
<path d="M16 21l-13-13h-3l16 16 16-16h-3l-13 13z"></path>
</svg>
</a>
activity_component
{% for mess in room_messages %}
<div class="activities__box">
<div class="activities__boxHeader roomListRoom__header">
<a href="{% url 'user-profile' mess.user.id %}" class="roomListRoom__author">
<div class="avatar avatar--small">
<img src="https://randomuser.me/api/portraits/women/11.jpg" />
</div>
<p>
@{{ mess.user }}
<span>{{ mess.mess.created|timesince }} ago</span>
</p>
</a>
<div class="roomListRoom__actions">
{% if mess.user == request.user %}
<a href="{% url 'delete-message' mess.id %}">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>remove</title>
<path
d="M27.314 6.019l-1.333-1.333-9.98 9.981-9.981-9.981-1.333 1.333 9.981 9.981-9.981 9.98 1.333 1.333 9.981-9.98 9.98 9.98 1.333-1.333-9.98-9.98 9.98-9.981z"
></path>
</svg>
</a>
{% endif %}
</div>
</div>
<div class="activities__boxContent">
<p>replied to post “<a href="{% url 'room' mess.room.id %}">{{ mess.room }}</a>”</p>
<div class="activities__boxRoomContent">
{{ mess }}
</div>
</div>
</div>
{% endfor %}
home.html
{% extends 'main.html' %}
{% block content %}
<main class="layout layout--3">
<div class="container">
<!-- Topics Start -->
<div class="topics">
{% include 'base/topic_component.html' %}
</div>
<!-- Topics End -->
<!-- Room List Start -->
<div class="roomList">
<div class="mobile-menu">
<form class="header__search">
<label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>search</title>
<path
d="M32 30.586l-10.845-10.845c1.771-2.092 2.845-4.791 2.845-7.741 0-6.617-5.383-12-12-12s-12 5.383-12 12c0 6.617 5.383 12 12 12 2.949 0 5.649-1.074 7.741-2.845l10.845 10.845 1.414-1.414zM12 22c-5.514 0-10-4.486-10-10s4.486-10 10-10c5.514 0 10 4.486 10 10s-4.486 10-10 10z"
></path>
</svg>
<input placeholder="Search for posts" />
</label>
</form>
<div class="mobile-menuItems">
<a class="btn btn--main btn--pill" href="#">Browse Topics</a>
<a class="btn btn--main btn--pill" href="#">Recent Activities</a>
</div>
</div>
<div class="roomList__header">
<div>
<h2>Study Room</h2>
<p>{{ room_count }} Rooms available</p>
</div>
<a class="btn btn--main" href="{% url 'create_room' %}">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>add</title>
<path
d="M16.943 0.943h-1.885v14.115h-14.115v1.885h14.115v14.115h1.885v-14.115h14.115v-1.885h-14.115v-14.115z"
></path>
</svg>
Create Room
</a>
</div>
{% include 'base/feed_component.html' %}
</div>
<!-- Room List End -->
<!-- Activities Start -->
<div class="activities">
<div class="activities__header">
<h2>Recent Activities</h2>
</div>
{% include 'base/activity_component.html' %}
</div>
<!-- Activities End -->
</div>
</main>
{% endblock content %}
22.profile
profile.html
{% extends 'main.html' %}
{% block content %}
<main class="profile-page layout layout--3">
<div class="container">
<!-- Topics Start -->
<div class="topics">
{% include 'base/topic_component.html' %}
</div>
<!-- Topics End -->
<!-- Room List Start -->
<div class="roomList">
<div class="profile">
<div class="profile__avatar">
<div class="avatar avatar--large active">
<img src="https://randomuser.me/api/portraits/men/11.jpg" />
</div>
</div>
<div class="profile__info">
<h3>{{ user.username }}</h3>
<p>@{{ user.username }}</p>
<a href="edit-user.html" class="btn btn--main btn--pill">Edit Profile</a>
</div>
<div class="profile__about">
<h3>About</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequuntur illo tenetur
facilis sunt nemo debitis quisquam hic atque aut? Ducimus alias placeat optio
accusamus repudiandae quis ab ex exercitationem rem?
</p>
</div>
</div>
<div class="roomList__header">
<div>
<h2>Study Rooms Hosted by {{ user.username}}</h2>
</div>
</div>
{% include 'base/feed_component.html' %}
</div>
<!-- Room List End -->
<!-- Activities Start -->
<div class="activities">
{% include 'base/activity_component.html' %}
</div>
<!-- Activities End -->
</div>
</main>
{% endblock %}
2.room.html
3.room_form
、、、
、、、
topic, created = Topic.objects.get_or_create(name=topic_name)
room_form.html
{% extends 'main.html' %}
{% block content %}
<main class="create-room layout">
<div class="container">
<div class="layout__box">
<div class="layout__boxHeader">
<div class="layout__boxTitle">
<a href="{% url 'home' %}">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>arrow-left</title>
<path
d="M13.723 2.286l-13.723 13.714 13.719 13.714 1.616-1.611-10.96-10.96h27.625v-2.286h-27.625l10.965-10.965-1.616-1.607z">
</path>
</svg>
</a>
<h3>Create/Update Study Room</h3>
</div>
</div>
<div class="layout__body">
<form class="form" action="" method="post">
{% csrf_token %}
<div class="form__group">
<label for="room_topic">Enter a topic</label>
<input required type="text" name="topic" id="room_topic" list="topic-list" />
<datalist id="topic-list">
<select id="room_topic">
{% for topic in topics %}
<option value="{{ topic.name }}">{{ topic.name }}</option>
{% endfor %}
</select>
</datalist>
</div>
<div class="form__group">
<label for="room_name">Room Name</label>
{{ form.name }}
</div>
<div class="form__group">
<label for="room_description">Room description</label>
{{ form.description }}
</div>
{# <div class="form__action">#}
{# <a class="btn btn--dark" href="{% url 'home' %}">Cancel</a>#}
{# <button class="btn btn--main" type="submit">Submit</button>#}
{# </div>#}
<div class="form__action">
<a class="btn btn--dark" href="{{request.META.HTTP_REFERER}}">Cancel</a>
<button class="btn btn--main" type="submit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</main>
{% endblock %}
views.py
@login_required(login_url='login')
def createRoom(request):
form = RoomForm()
topics = Topic.objects.all()
if request.method == 'POST':
topic_name = request.POST.get('topic')
topic, created = Topic.objects.get_or_create(name=topic_name)
Room.objects.create(
host=request.user,
topic=topic,
name=request.POST.get('name'),
description=request.POST.get('description')
)
return redirect('home')
context={"form":form,"topics":topics}
return render(request,'base/room_form.html',context)
@login_required(login_url='login')
def updateRoom(request,pk):
room = Room.objects.get(id=pk)
form = RoomForm(instance=room)
topics = Topic.objects.all()
if request.user != room.host:
return HttpResponse('Your are not allowed here!!')
if request.method == 'POST':
topic_name = request.POST.get('topic')
topic, created = Topic.objects.get_or_create(name=topic_name)
room.topic =topic
room.name = request.POST.get('name')
room.description = request.POST.get('description')
room.save()
return redirect('home')
context = {'form': form, 'topics': topics, 'room': room}
return render(request,'base/room_form.html',context)
4.用户资料 界面update-user.html
edit-user.html 重命名 update-user.html
{% extends 'main.html' %}
{% block content %}
<main class="update-account layout">
<div class="container">
<div class="layout__box">
<div class="layout__boxHeader">
<div class="layout__boxTitle">
<a href="profile.html">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32"
viewBox="0 0 32 32">
<title>arrow-left</title>
<path
d="M13.723 2.286l-13.723 13.714 13.719 13.714 1.616-1.611-10.96-10.96h27.625v-2.286h-27.625l10.965-10.965-1.616-1.607z">
</path>
</svg>
</a>
<h3>Edit your profile</h3>
</div>
</div>
<div class="layout__body">
<form class="form" action="" method="post">
{% csrf_token %}
{% for foo in form %}
<div class="form__group">
<label for="profile_pic">{{ foo.label }}</label>
{{ foo }}
</div>
{% endfor %}
<div class="form__action">
<a class="btn btn--dark" href="{% url 'user-profile' user.id %}">Cancel</a>
<button class="btn btn--main" type="submit">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
10.评论功能 message
5.delete.html
6. login_register.html
{% extends 'main.html' %}
{% block content %}
<main class="auth layout">
{% if page == 'login' %}
<div class="container">
<div class="layout__box">
<div class="layout__boxHeader">
<div class="layout__boxTitle">
<h3>Login</h3>
</div>
</div>
<div class="layout__body">
<h2 class="auth__tagline">Find your study partner</h2>
<form class="form" action="" method="POST">
{% csrf_token %}
<div class="form__group form__group">
<label for="room_name">Username</label>
<input id="username" name="username" type="text" />
</div>
<div class="form__group">
<label for="password">Password</label>
<input
id="password"
name="password"
type="password"
placeholder="••••••••" />
</div>
<button class="btn btn--main" type="submit">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>lock</title>
<path
d="M27 12h-1v-2c0-5.514-4.486-10-10-10s-10 4.486-10 10v2h-1c-0.553 0-1 0.447-1 1v18c0 0.553 0.447 1 1 1h22c0.553 0 1-0.447 1-1v-18c0-0.553-0.447-1-1-1zM8 10c0-4.411 3.589-8 8-8s8 3.589 8 8v2h-16v-2zM26 30h-20v-16h20v16z">
</path>
<path
d="M15 21.694v4.306h2v-4.306c0.587-0.348 1-0.961 1-1.694 0-1.105-0.895-2-2-2s-2 0.895-2 2c0 0.732 0.413 1.345 1 1.694z">
</path>
</svg>
Login
</button>
</form>
<div class="auth__action">
<p>Haven't signed up yet?</p>
<a href="{% url 'register' %}" class="btn btn--link">Sign Up</a>
</div>
</div>
</div>
</div>
{% else %}
<div class="container">
<div class="layout__box">
<div class="layout__boxHeader">
<div class="layout__boxTitle">
<h3>Register</h3>
</div>
</div>
<div class="layout__body">
<h2 class="auth__tagline">Find your study partner</h2>
<form class="form" action="" method="POST">
{% csrf_token %}
{% for field in form %}
<div class="form__group form__group">
<label for="room_name">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<button class="btn btn--main" type="submit">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>lock</title>
<path
d="M27 12h-1v-2c0-5.514-4.486-10-10-10s-10 4.486-10 10v2h-1c-0.553 0-1 0.447-1 1v18c0 0.553 0.447 1 1 1h22c0.553 0 1-0.447 1-1v-18c0-0.553-0.447-1-1-1zM8 10c0-4.411 3.589-8 8-8s8 3.589 8 8v2h-16v-2zM26 30h-20v-16h20v16z">
</path>
<path
d="M15 21.694v4.306h2v-4.306c0.587-0.348 1-0.961 1-1.694 0-1.105-0.895-2-2-2s-2 0.895-2 2c0 0.732 0.413 1.345 1 1.694z">
</path>
</svg>
Register
</button>
</form>
<div class="auth__action">
<p>Already signed up yet?</p>
<a href="{% url 'login' %}" class="btn btn--link">Sign Up</a>
</div>
</div>
</div>
</div>
{% endif %}
</main>
{% endblock content %}
23.mobile responsive响应式设计
要使网页在移动设备上具有响应式设计,你需要采取一些措施确保页面能够根据设备的屏幕大小和方向进行自适应调整。
activity.html
{% extends 'main.html' %}
{% block content %}
<main class="layout">
<div class="container">
<div class="layout__box">
<div class="layout__boxHeader">
<div class="layout__boxTitle">
<a href="{% url 'home' %}">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>arrow-left</title>
<path
d="M13.723 2.286l-13.723 13.714 13.719 13.714 1.616-1.611-10.96-10.96h27.625v-2.286h-27.625l10.965-10.965-1.616-1.607z"
></path>
</svg>
</a>
<h3>Recent Activities</h3>
</div>
</div>
<div class="activities-page layout__body">
{% for message in room_messages %}
<div class="activities__box">
<div class="activities__boxHeader roomListRoom__header">
<a href="{% url 'user-profile' message.user.id %}" class="roomListRoom__author">
<div class="avatar avatar--small">
<img src="https://randomuser.me/api/portraits/women/11.jpg" />
</div>
<p>
@{{ message.user }}
<span>{{ message.created|timesince }} ago</span>
</p>
</a>
{% if message.user == request.user %}
<div class="roomListRoom__actions">
<a href="{% url 'delete-message' message.id %}">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>remove</title>
<path
d="M27.314 6.019l-1.333-1.333-9.98 9.981-9.981-9.981-1.333 1.333 9.981 9.981-9.981 9.98 1.333 1.333 9.981-9.98 9.98 9.98 1.333-1.333-9.98-9.98 9.98-9.981z"
></path>
</svg>
</a>
</div>
{% endif %}
</div>
<div class="activities__boxContent">
<p>replied to post “<a href="{% url 'room' message.room.id %}">{{ message.room.name }}</a>”</p>
<div class="activities__boxRoomContent">
{{ message.body }}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</main>
<script src="script.js"></script>
{% endblock %}
topics.html
{% extends 'main.html' %}
{% block content %}
<main class="create-room layout">
<div class="container">
<div class="layout__box">
<div class="layout__boxHeader">
<div class="layout__boxTitle">
<a href="{% url 'home' %}">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>arrow-left</title>
<path
d="M13.723 2.286l-13.723 13.714 13.719 13.714 1.616-1.611-10.96-10.96h27.625v-2.286h-27.625l10.965-10.965-1.616-1.607z"
></path>
</svg>
</a>
<h3>Browse Topics</h3>
</div>
</div>
<div class="topics-page layout__body">
<form class="header__search" method="get">
<label>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>search</title>
<path
d="M32 30.586l-10.845-10.845c1.771-2.092 2.845-4.791 2.845-7.741 0-6.617-5.383-12-12-12s-12 5.383-12 12c0 6.617 5.383 12 12 12 2.949 0 5.649-1.074 7.741-2.845l10.845 10.845 1.414-1.414zM12 22c-5.514 0-10-4.486-10-10s4.486-10 10-10c5.514 0 10 4.486 10 10s-4.486 10-10 10z"
></path>
</svg>
<input type="text" name="q" placeholder="Search for posts" />
</label>
</form>
<ul class="topics__list">
<li>
<a href="/" class="active">All <span>{{ topics.count }}</span></a>
</li>
{% for topic in topics %}
<li>
<a href="{% url 'home' %}?q={{ topic.name }}" class="active">{{ topic.name }} <span>{{ topic.room_set.all.count }}</span></a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</main>
<script src="script.js"></script>
{% endblock %}
24.REST Framework
前后端分离
1)后端
......
2 - Requests and responses - Django REST framework
2)前端
一个 Django 应用程序,将跨源资源共享 (CORS) 标头添加到响应中。
这允许从其他来源向您的 Django 应用程序发出浏览器内请求。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Cool Rooms</title>
</head>
<body>
<h1>Cool Rooms</h1>
<div id="rooms-container">
</div>
</body>
<script>
let getRooms = async () => {
let response = await fetch("http://localhost:8000/api/rooms/")
let rooms = await response.json()
console.log("ROOMS:",rooms)
}
getRooms()
</script>
</html>