1.准备工作

M层:生成虚假数据

from django.db import models
from faker import Factory
# Create your models here. class Video(models.Model):
"""视频字段列表"""
title = models.CharField(null=True, blank=True, max_length=300) # 视频标题
content = models.TextField(null=True) # 视频内容
url_image = models.URLField(null=True, blank=True) # 视频url地址
new_choice = models.BooleanField(default=False) # 视频分类用的
editors_choice = models.BooleanField(default=False) def __str__(self):
return self.title # f = open('/Users/Administrator/Desktop/111.txt', 'r')
# fake = Factory.create()
#
# for url in f.readlines():
# v = Video(
# title=fake.text(max_nb_chars=90),
# content=fake.text(max_nb_chars=3000),
# url_image=url,
# new_choice=fake.pybool(),
# editors_choice=fake.pybool(),
# )
# v.save()
https://pixabay.com/static/uploads/photo/2016/08/25/19/10/mill-1620440__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/10/17/47/eggplant-1659784__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/16/17/20/elevator-1598431__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/08/13/58/algodones-dunes-1654439__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/08/20/52/milky-way-1655504__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/10/19/56/lions-1660044__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/10/23/48/bridge-1660417__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/08/18/38/dovetail-1655098__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/17/18/15/tabletop-photography-1601184__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/04/20/14/sunset-1645103__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/19/18/50/fruit-1605921__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/15/20/29/olive-oil-1596417__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/01/13/35/doll-1636128__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/08/12/00/starry-sky-1654074__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/01/19/43/sunrise-1637376__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/01/19/53/pocket-watch-1637396__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/25/11/01/landscape-1619283__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/29/21/29/lotus-flower-1629225__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/07/16/19/bremen-town-musicians-1651945__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/25/19/10/mill-1620440__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/27/22/55/sunset-1625073__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/30/11/59/cobweb-1630493__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/01/18/24/rk5161-1636868__340.jpg
https://pixabay.com/static/uploads/photo/2016/07/27/20/03/berries-1546125__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/26/20/44/elan-1623088__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/09/21/54/yellowstone-national-park-1581879__340.jpg
https://pixabay.com/static/uploads/photo/2016/07/15/15/55/dachshund-1519374__340.jpg
https://pixabay.com/static/uploads/photo/2016/05/28/07/04/women-1421096__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/28/17/54/sunset-1626515__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/13/15/28/lake-tahoe-1590923__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/11/09/40/water-lily-1585178__340.jpg
https://pixabay.com/static/uploads/photo/2016/07/31/19/26/fischer-1559753__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/11/22/35/tomatoes-1587130__340.jpg
https://pixabay.com/static/uploads/photo/2016/04/22/16/42/mt-fuji-1346096__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/12/23/47/yosemite-1590013__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/01/20/13/girl-1561989__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/26/17/14/geese-1622692__340.jpg
https://pixabay.com/static/uploads/photo/2016/03/09/03/49/tarantula-nebula-1245253__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/11/23/55/redwood-national-park-1587301__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/26/17/33/landscape-1622739__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/03/21/40/eurasian-eagle-owl-1642795__340.jpg
https://pixabay.com/static/uploads/photo/2016/08/28/22/59/dahlia-1627138__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/03/14/19/motion-1641793__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/04/08/46/butterfly-1643510__340.jpg
https://pixabay.com/static/uploads/photo/2015/12/17/02/22/milky-way-1096815__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/04/12/05/sun-flower-1643794__340.jpg
https://pixabay.com/static/uploads/photo/2015/08/20/02/46/arch-896900__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/03/23/17/flowers-1642964__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/03/18/44/dahlia-1642464__340.jpg
https://pixabay.com/static/uploads/photo/2016/09/03/14/15/motion-1641781__340.jpg

图片url

V层:

from django.shortcuts import render
from website.models import Video
# Create your views here. def listing(request):
"""listing主页视图"""
context = {}
video_list = Video.objects.all() # 获取所有的视频信息
context['video_list'] = video_list
return render(request, 'listing.html', context)
from django.conf.urls import url
from django.contrib import admin
from website.views import listing urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/', listing, name='listing'),
]

url

T层

<img src="{{ video.url_image }}" alt="" style="height:200px;object-fit: cover;">
<!DOCTYPE html>
{% load staticfiles %}
<html> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/list_custom.css' %}" media="screen" title="no title" charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Oswald|Raleway" rel="stylesheet"> </head> <body>
<div class="ui inverted top fixed menu borderless red menu">
<div class="header item">
<div class="ui image">
<img src="{% static 'images/tenlogo.png' %}" alt="">
</div>
</div> <div class="right menu">
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="{% static 'images/hou30.jpg' %}" alt="">
</div> <span>admin</span> </h5>
</div>
<div class="item"> <a href="#logout/" class="ui inverted circular button">Logout</a> </div>
</div>
</div>
<div class="ui inverted segment container nav">
<div class="ui three borderless item menu">
<a class="item">
All
</a>
<a class="item">
New
</a> <a class="active item" href="#list/editors">
Editor's
</a>
</div>
</div> <div class="ui basic segment container content"> <div class="ui three column grid"> {% for video in video_list %}
<div class="column"> <a class="ui fluid card" href="#detail/215">
<div class="image">
<img src="{{ video.url_image }}" alt="" style="height:200px;object-fit: cover;">
</div>
</a> <div class="title header" href="/detail/215">{{ video.title }}</div>
<i class="icon grey unhide"></i>
<span style="color:#bbbbbb">10K</span>
<span class="" style="color:rgb(226, 226, 226)">|</span>
<i class="icon grey checkmark"></i>
<span style="color:#bbbbbb"> 10 people got it</span>
</div>
{% endfor %} </div>
</div> <div class="ui center aligned very padded vertical segment container">
<div class="ui pagination menu"> <a href="#" class="item">
<i class="icon red left arrow"></i>
</a> <a href="#" class="item">
<i class="icon red right arrow"></i>
</a>
</div>
</div> </body> </html>
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'website',
] TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates').replace('\\','/')],
'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',
],
},
},
]

setting

2.V层实现分页功能

  1 V层:djang自带的分页器

from django.shortcuts import render, Http404
from website.models import Video
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
# Create your views here. def listing(request):
"""listing主页视图"""
context = {}
video_list = Video.objects.all() # 获取所有的视频信息
page_data = Paginator(video_list, 9) # 每页9个数据 try:
video_list = page_data.page(request.GET.get('page')) # get方法取哪一页
except EmptyPage:
video_list = page_data.page(page_data.num_pages) # ?page=999加载最后一页
# raise Http404('Not found this page') 第二种方法
except PageNotAnInteger:
video_list = page_data.page(1) # ?page=23daf 加载第一页 context['video_list'] = video_list
return render(request, 'listing.html', context)

    

  2.T层分页

 <div class="ui center aligned very padded vertical segment container">
<div class="ui pagination menu"> {% if video_list.has_previous %}
<a href="?page={{ video_list.previous_page_number }}" class="item">
<i class="icon red left arrow"></i>
</a>
{% else %}
<a href="?page={{ video_list.start_index }}" class="disabled item">
<i class="icon left arrow"></i>
</a>
{% endif %} {% if video_list.has_next %}
<a href="?page={{ video_list.next_page_number }}" class="item">
<i class="icon red right arrow"></i>
</a>
{% else %}
<a href="?page={{ video_list.end_index }}" class="disabled item">
<i class="icon right arrow"></i>
</a>
{% endif %} </div>
</div>

3.文章分类

  1.错误: 注意  ^listing/$

    url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量

  2 M层 不变

  3 url

from django.conf.urls import url
from django.contrib import admin
from website.views import listing urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
]

  

4 V层

from django.shortcuts import render, Http404
from website.models import Video
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
# Create your views here. def listing(request, cate=None):
"""listing主页视图"""
context = {}
if cate is None:
video_list = Video.objects.all()
else:
if cate == 'new':
video_list = Video.objects.filter(new_choice=True)
elif cate == 'editors':
video_list = Video.objects.filter(editors_choice=True)
else:
video_list = Video.objects.all() # 获取所有的视频信息 page_data = Paginator(video_list, 9) # 每页9个数据
page_num = request.GET.get('page') try:
video_list = page_data.page(page_num) # get方法取哪一页
except EmptyPage:
video_list = page_data.page(page_data.num_pages) # ?page=999加载最后一页
# raise Http404('Not found this page') 第二种方法
except PageNotAnInteger:
video_list = page_data.page(1) # ?page=23daf 加载第一页 context['video_list'] = video_list
return render(request, 'listing.html', context)

  5 M层

        <div class="ui  three borderless  item  menu">

            <a class="active item" href="{% url 'listing' %}">All</a>

            {% if 'new' in request.path %}
<a class="active item" href="{% url 'listing' %}new">New</a>
{% else %}
<a class="item" href="{% url 'listing' %}new">New</a>
{% endif %} {% if 'editors' in request.path %}
<a class="active item" href="{% url 'listing' %}editors">Editor's</a>
{% else %}
<a class="item" href="{% url 'listing' %}editors">Editor's</a>
{% endif %} </div>

    

4.上传本地图片

1 M层

from django.db import models
from faker import Factory
# Create your models here. class Video(models.Model):
"""视频字段列表"""
title = models.CharField(null=True, blank=True, max_length=300) # 视频标题
content = models.TextField(null=True) # 视频内容
url_image = models.URLField(null=True, blank=True) # 视频url地址 cover = models.FileField(upload_to='cover_image', null=True) # 上传图片字段 new_choice = models.BooleanField(default=False) # 视频分类用的
editors_choice = models.BooleanField(default=False) def __str__(self):
return self.title

  2 V层不变

  3 url Debug模式

from django.conf.urls import url
from django.contrib import admin
from website.views import listing from django.conf import settings
from django.conf.urls.static import static urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
] if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

  

  setting

STATIC_URL = '/static/'
MEDIA_URL = '/upload/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'upload').replace("//", "/")

  4.T层

                        <a class="ui fluid card" href="#">
<div class="image">
{% if video.cover %}
<img src="/upload/{{ video.cover }}" alt="" style="height:200px;object-fit: cover;">
{% else %}
<img src="{{ video.url_image }}" alt="" style="height:200px;object-fit: cover;">
{% endif %} </div>
</a>

5.登录页面

from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate,login

1 form.py文件

from django import forms

class LoginForm(forms.Form):
"""login登录表单"""
username = forms.CharField()
password = forms.CharField()

2 V层

  方法1:authenticate验证form表单

from django.shortcuts import render, Http404, redirect, HttpResponse
from website.models import Video
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate,login
from website.form import LoginForm
# Create your views here. def detail_login(request):
"""登录view"""
context = {}
if request.method == "GET":
form = LoginForm
if request.method == "POST":
form = LoginForm(request.POST)
print(form)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password) if user:
login(request, user)
return redirect(to='listing')
else:
return HttpResponse("<h1>Not found this user</h1>") context['form'] = form
return render(request, 'login_regist.html', context)

  方法2:AuthenticationForm验证

from django.shortcuts import render, Http404, redirect, HttpResponse
from website.models import Video
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate,login
from website.form import LoginForm
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
# Create your views here. # Django自带的"AuthenticationForm 登录验证
def detail_login(request):
"""登录验证"""
context = {}
if request.method == "GET":
form = AuthenticationForm
if request.method == "POST":
form = AuthenticationForm(data=request.POST)
if form.is_valid():
login(request, form.get_user())
return redirect(to='listing')
context['form'] = form
return render(request, 'login_regist.html', context)

3. url

from website.views import listing,detail_login

from django.conf import settings
from django.conf.urls.static import static urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
url(r'^login/$', detail_login, name='detail_login'),
]

4.T层

                <form class="ui form" method="post">
{{ form.as_p }}
{% csrf_token %}
<button class="ui inverted red circular right floated button" type="submit">Done</button>
</form>

6.注册

from django.contrib.auth.forms import UserCreationForm,

1. V层:UserCreationForm注册

from django.shortcuts import render, Http404, redirect, HttpResponse
from website.models import Video
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate,login
from website.form import LoginForm
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
# Create your views here. # 注册
def detail_register(request):
"""注册功能"""
context = {}
if request.method == "GET":
form = UserCreationForm
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect(to="detail_login") context['form'] = form
return render(request, 'login_regist.html', context)

  2. url

from django.conf.urls import url
from django.contrib import admin
from website.views import listing,detail_login, detail_register from django.conf import settings
from django.conf.urls.static import static urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
url(r'^login/$', detail_login, name='detail_login'),
url(r'^register/$', detail_register, name='detail_register'),
]

3.T层

                <form class="ui form" method="post">
{{ form.as_p }}
{% csrf_token %}
<button class="ui inverted red circular right floated button" type="submit">Done</button>
</form>

      

7.自定义form表单

                <form class="ui form error" method="post">

                    {% if form.errors %}
<div class="ui error message">
{{ form.errors }}
</div> {% for field in form %}
<div class="{{ field.errors|yesno:'error, ' }} field">
{{ field.label }}
{{ field }}
</div>
{% endfor %} {% else %}
{% for field in form %}
<div class="field">
{{ field.label }}
{{ field }}
</div>
{% endfor %} {% endif %} {% csrf_token %} <button class="ui inverted red circular right floated button" type="submit">Done</button>
</form>
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/list_custom.css' %}" media="screen" title="no title" charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Play" rel="stylesheet">
<style type="text/css">
body {
background: url({% static 'images/super_blur_back2.jpg' %});
background-size: cover;
} .ui.grid.divided.segment.container{
min-height: 400px;
width:600px !important;
border:rgba(255, 0, 0, 0);
position: absolute;
left: 50%;
top:40%;
transform: translate(-50%,-50%);
} .five.wide.column {
background: url({% static 'images/red_regi.jpg' %});
background-size: cover;
background-position: 60% 0%;
} form {
margin-top: 60px;
}
h1,h3,h4{
font-family: 'Play', sans-serif !important; }
</style>
</head> <body>
<div class="ui grid divided segment container">
<div class="five wide column"> <h4 class="ui inverted header"> <i class="angle left icon"></i>
</h4> <h1 class="ui inverted center aligned header" style="font-size: 40px;margin-top:55px">
<p class="sub header">
Welcome to
</p>
10MINs
</h1> </div> <div class="eleven wide column"> {% if 'register' in request.path %}
<h4 class="ui inverted right aligned header">
<a href="{% url 'detail_login' %}" style="color:#ff695e;">or LOGIN</a>
</h4>
{% elif 'login' in request.path %}
<h4 class="ui inverted right aligned header">
<a href="{% url 'detail_register' %}" style="color:#ff695e;">or REGISTER</a>
</h4>
{% endif %} <form class="ui form error" method="post"> {% if form.errors %}
<div class="ui error message">
{{ form.errors }}
</div> {% for field in form %}
<div class="{{ field.errors|yesno:'error, ' }} field">
{{ field.label }}
{{ field }}
</div>
{% endfor %} {% else %}
{% for field in form %}
<div class="field">
{{ field.label }}
{{ field }}
</div>
{% endfor %} {% endif %} {% csrf_token %} <button class="ui inverted red circular right floated button" type="submit">Done</button>
</form> </div>
</div>
</body>
</html>

8 .登出

  from django.contrib.auth.views import logout

  1 M层

  2 V层

  3 url

from website.views import listing,detail_login, detail_register
from django.contrib.auth.views import logout urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
url(r'^login/$', detail_login, name='detail_login'),
url(r'^register/$', detail_register, name='detail_register'),
url(r'^logout/$', logout, {'next_page':'/listing'}, name='logout'), ]

4 T层

   <div class="right menu">
{% if request.user.is_authenticated %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="/upload/{{ request.user.profile.profile_image }}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'logout' %}" class="ui inverted circular button">Logout</a>
</div> {% else %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="{% static 'images/hou30.jpg' %}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'detail_login' %}" class="ui inverted circular button">Signip/Login</a>
</div>
{% endif %}
</div>

9.扩展用户资料

1 M层

from django.contrib.auth.models import User
from django.db import models
from faker import Factory
from django.contrib.auth.models import User
# Create your models here. class UserProfile(models.Model):
"""扩展用户资料"""
belong_to = models.OneToOneField(to=User, related_name='profile')
profile_image = models.FileField(upload_to='profile_image')

  

  T层

                            <div class="ui mini circular image">
<img src="/upload/{{ request.user.profile.profile_image }}" alt="">
</div>
      <div class="right menu">
{% if request.user.is_authenticated %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="/upload/{{ request.user.profile.profile_image }}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'logout' %}" class="ui inverted circular button">Logout</a>
</div> {% else %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="{% static 'images/hou30.jpg' %}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'detail_login' %}" class="ui inverted circular button">Signip/Login</a>
</div>
{% endif %}
</div>

9 详情页面

  V层

def detail(request,page_num):
"""详情页"""
context = {}
video = Video.objects.get(id=page_num)
context['video'] = video
return render(request,'detail.html',context)

  url

from website.views import listing,detail_login, detail_register, detail
from django.contrib.auth.views import logout urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
url(r'^login/$', detail_login, name='detail_login'),
url(r'^register/$', detail_register, name='detail_register'),
url(r'^logout/$', logout, {'next_page':'/listing'}, name='logout'),
url(r'^detail/(?P<page_num>\d+)$', detail, name='detail'),
]

  T层

        <h1 class="ui header">{{ video.title }}</h1>
<i class="icon grey unhide"></i>
<span style="color:#bbbbbb">10K</span>
<span class="" style="color:#e2e2e2">|</span>
<i class="icon grey checkmark"></i>
<span style="color:#bbbbbb">5673 people got it</span>
<p>
{{ video.content }}
</p>
<!DOCTYPE html>
{% load staticfiles %}
<html> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/detail.css' %}" media="screen" title="no title" charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Oswald|Raleway" rel="stylesheet">
</head> <body>
<div class="ui inverted fixed menu borderless red menu">
<div class="item">
<div class="ui image" >
<a href="{% url 'listing' %}">
<img src="{% static 'images/tenlogo.png' %}" alt="">
</a>
</div>
</div> <div class="right menu">
{% if request.user.is_authenticated %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="/upload/{{ request.user.profile.profile_image }}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'logout' %}" class="ui inverted circular button">Logout</a>
</div> {% else %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="{% static 'images/hou30.jpg' %}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'detail_login' %}" class="ui inverted circular button">Signip/Login</a>
</div>
{% endif %}
</div>
</div> <div class="ui vertical inverted detail segment"></div> <div class="ui basic segment container"> <h1 class="ui header">{{ video.title }}</h1>
<i class="icon grey unhide"></i>
<span style="color:#bbbbbb">10K</span>
<span class="" style="color:#e2e2e2">|</span>
<i class="icon grey checkmark"></i>
<span style="color:#bbbbbb">5673 people got it</span>
<p>
{{ video.content }}
</p> <div class="ui divider"></div> <form class="ui form" action="" method="post"> <button class="ui tiny button" type="submit" name="vote" value="like"> <i class="icon checkmark"></i>
Get it!
</button> <button class="ui red tiny button" type="submit" name="vote" value="normal">
<i class="icon bomb"></i>
Hmmm...
</button> <button class="ui secondary circular tiny right floated button">
<i class="pin icon"></i>
Saved
</button> </form>
</div> </body> </html>

10 投票功能

M层

class Ticket(models.Model):
"""投票字段"""
voter = models.ForeignKey(to=UserProfile, related_name="voter_tickets")
video = models.ForeignKey(to=Video, related_name='tickets') VOTE_CHOICES = (
('like','like'),
('dislike', 'dislike'),
('normal', 'normal'),
) choice = models.CharField(choices=VOTE_CHOICES, max_length=10) def __str__(self):
return str(self.id)

注册

from django.contrib import admin
from website.models import Video, UserProfile, Ticket # Register your models here. admin.site.register(Video)
admin.site.register(UserProfile)
admin.site.register(Ticket)

V层:获取投票和内容

def detail(request,page_num):
"""详情页"""
context = {}
video = Video.objects.get(id=page_num) # 投票的是哪个视频
voter_id = request.user.profile.id # 投票的是哪个用户
print(voter_id)
try:
user_ticker_for_this_video = Ticket.objects.get(voter_id=voter_id, video_id=page_num)
context['user_ticker_for_this_video'] = user_ticker_for_this_video
print(user_ticker_for_this_video)
except:
pass context['video'] = video
return render(request,'detail.html',context)

T层

<form class="ui form" action="" method="post">
{% csrf_token %}
{% if user_ticker_for_this_video.choice == 'like' %}
<button class="ui red tiny button" type="submit" name="vote" value="normal">
<i class="icon checkmark"></i>Get it!
</button>
<button class="ui tiny button" type="submit" name="vote" value="dislike">
<i class="icon bomb"></i>Hmmm...
</button>
{% elif user_ticker_for_this_video.choice == 'dislike'%}
<button class="ui tiny button" type="submit" name="vote" value="like">
<i class="icon checkmark"></i>Get it!
</button>
<button class="ui red tiny button" type="submit" name="vote" value="normal">
<i class="icon bomb"></i>Hmmm...
</button> {% else %}
<button class="ui tiny button" type="submit" name="vote" value="like">
<i class="icon checkmark"></i>Get it!
</button>
<button class="ui tiny button" type="submit" name="vote" value="dislike">
<i class="icon bomb"></i>Hmmm...
</button>
{% endif %} <button class="ui secondary circular tiny right floated button">
<i class="pin icon"></i>Saved
</button> </form>

11 投票post

M层

from django.db import models
from faker import Factory
from django.contrib.auth.models import User
# Create your models here. class UserProfile(models.Model):
"""扩展用户资料"""
belong_to = models.OneToOneField(to=User, related_name='profile')
profile_image = models.FileField(upload_to='profile_image') class Video(models.Model):
"""视频字段列表"""
title = models.CharField(null=True, blank=True, max_length=300) # 视频标题
content = models.TextField(null=True) # 视频内容
url_image = models.URLField(null=True, blank=True) # 视频url地址 cover = models.FileField(upload_to='cover_image', null=True) # 上传图片字段 new_choice = models.BooleanField(default=False) # 视频分类用的
editors_choice = models.BooleanField(default=False) def __str__(self):
return self.title # f = open('/Users/Administrator/Desktop/111.txt', 'r')
# fake = Factory.create()
#
# for url in f.readlines():
# v = Video(
# title=fake.text(max_nb_chars=90),
# content=fake.text(max_nb_chars=3000),
# url_image=url,
# new_choice=fake.pybool(),
# editors_choice=fake.pybool(),
# )
# v.save() class Ticket(models.Model):
"""投票字段"""
voter = models.ForeignKey(to=UserProfile, related_name="voter_tickets")
video = models.ForeignKey(to=Video, related_name='tickets') VOTE_CHOICES = (
('like','like'),
('dislike', 'dislike'),
('normal', 'normal'),
) choice = models.CharField(choices=VOTE_CHOICES, max_length=10) def __str__(self):
return str(self.id)

V层

def detail_voter_post(request,page_num):
"""post提交投票"""
voter_id = request.user.profile.id # 投票的是哪个用户
try:
user_ticker_for_this_video = Ticket.objects.get(voter_id=voter_id, video_id=page_num)
user_ticker_for_this_video.choice = request.POST['vote']
user_ticker_for_this_video.save()
except ObjectDoesNotExist:
new_ticket = Ticket(voter_id=voter_id, video_id=page_num, choice=request.POST['vote'])
print(new_ticket)
new_ticket.save() return redirect(to='detail',page_num=page_num)
from django.shortcuts import render, Http404, redirect, HttpResponse
from website.models import Video,Ticket, UserProfile
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate,login
from website.form import LoginForm
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.core.exceptions import ObjectDoesNotExist
# Create your views here. # Django自带的"AuthenticationForm 登录验证
def detail_login(request):
"""登录验证"""
context = {}
if request.method == "GET":
form = AuthenticationForm
if request.method == "POST":
form = AuthenticationForm(data=request.POST)
if form.is_valid():
login(request, form.get_user())
return redirect(to='listing')
context['form'] = form
return render(request, 'login_regist.html', context) # 方法2:form表单验证
# def detail_login(request):
# """登录view"""
# context = {}
# if request.method == "GET":
# form = LoginForm
# if request.method == "POST":
# form = LoginForm(request.POST)
# print(form)
# if form.is_valid():
# username = form.cleaned_data['username']
# password = form.cleaned_data['password']
# user = authenticate(username=username, password=password)
#
# if user:
# login(request, user)
# return redirect(to='listing')
# else:
# return HttpResponse("<h1>Not found this user</h1>")
#
# context['form'] = form
# return render(request, 'login_regist.html', context) # 注册
def detail_register(request):
"""注册功能"""
context = {}
if request.method == "GET":
form = UserCreationForm
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect(to="detail_login") context['form'] = form
return render(request, 'login_regist.html', context) def listing(request, cate=None):
"""listing主页视图"""
context = {}
if cate is None:
video_list = Video.objects.all()
else:
if cate == 'new':
video_list = Video.objects.filter(new_choice=True)
elif cate == 'editors':
video_list = Video.objects.filter(editors_choice=True)
else:
video_list = Video.objects.all() # 获取所有的视频信息 page_data = Paginator(video_list, 9) # 每页9个数据
page_num = request.GET.get('page') try:
video_list = page_data.page(page_num) # get方法取哪一页
except EmptyPage:
video_list = page_data.page(page_data.num_pages) # ?page=999加载最后一页
# raise Http404('Not found this page') 第二种方法
except PageNotAnInteger:
video_list = page_data.page(1) # ?page=23daf 加载第一页 context['video_list'] = video_list
return render(request, 'listing.html', context) def detail(request,page_num):
"""详情页"""
context = {}
video = Video.objects.get(id=page_num) # 投票的是哪个视频
voter_id = request.user.profile.id # 投票的是哪个用户
#print(voter_id)
try:
user_ticker_for_this_video = Ticket.objects.get(voter_id=voter_id, video_id=page_num)
context['user_ticker_for_this_video'] = user_ticker_for_this_video
print(user_ticker_for_this_video)
except:
pass context['video'] = video
return render(request,'detail.html',context) def detail_voter_post(request,page_num):
"""post提交投票"""
voter_id = request.user.profile.id # 投票的是哪个用户
try:
user_ticker_for_this_video = Ticket.objects.get(voter_id=voter_id, video_id=page_num)
user_ticker_for_this_video.choice = request.POST['vote']
user_ticker_for_this_video.save()
except ObjectDoesNotExist:
new_ticket = Ticket(voter_id=voter_id, video_id=page_num, choice=request.POST['vote'])
print(new_ticket)
new_ticket.save() return redirect(to='detail',page_num=page_num)

url

from website.views import listing,detail_login, detail_register, detail,detail_voter_post
from django.contrib.auth.views import logout urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
url(r'^login/$', detail_login, name='detail_login'),
url(r'^register/$', detail_register, name='detail_register'),
url(r'^logout/$', logout, {'next_page':'/listing'}, name='logout'),
url(r'^detail/(?P<page_num>\d+)$', detail, name='detail'),
url(r'^detail/vote/(?P<page_num>\d+)$', detail_voter_post, name='detail_voter_post'),
"""tenmins URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static from website.views import listing,detail_login, detail_register, detail,detail_voter_post
from django.contrib.auth.views import logout urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^listing/$', listing, name='listing'),
url(r'^listing/(?P<cate>[A-Za-z]+)$', listing, name='listing'), # cate变量
url(r'^login/$', detail_login, name='detail_login'),
url(r'^register/$', detail_register, name='detail_register'),
url(r'^logout/$', logout, {'next_page':'/listing'}, name='logout'),
url(r'^detail/(?P<page_num>\d+)$', detail, name='detail'),
url(r'^detail/vote/(?P<page_num>\d+)$', detail_voter_post, name='detail_voter_post'),
] if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

T层

        <form class="ui form" action="{% url 'detail_voter_post' video.id %}" method="post">
<!DOCTYPE html>
{% load staticfiles %}
<html> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/detail.css' %}" media="screen" title="no title" charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Oswald|Raleway" rel="stylesheet">
</head> <body>
<div class="ui inverted fixed menu borderless red menu">
<div class="item">
<div class="ui image" >
<a href="{% url 'listing' %}">
<img src="{% static 'images/tenlogo.png' %}" alt="">
</a>
</div>
</div> <div class="right menu">
{% if request.user.is_authenticated %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="/upload/{{ request.user.profile.profile_image }}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'logout' %}" class="ui inverted circular button">Logout</a>
</div> {% else %}
<div class="item">
<h5 class="ui inverted header">
<div class="ui mini circular image">
<img src="{% static 'images/hou30.jpg' %}" alt="">
</div>
<span>{{ request.user.username }}</span>
</h5>
</div>
<div class="item">
<a href="{% url 'detail_login' %}" class="ui inverted circular button">Signip/Login</a>
</div>
{% endif %}
</div>
</div> <div class="ui vertical inverted detail segment"></div> <div class="ui basic segment container"> <h1 class="ui header">{{ video.title }}</h1>
<i class="icon grey unhide"></i>
<span style="color:#bbbbbb">10K</span>
<span class="" style="color:#e2e2e2">|</span>
<i class="icon grey checkmark"></i>
<span style="color:#bbbbbb">5673 people got it</span>
<p>
{{ video.content }}
</p> <div class="ui divider"></div> <form class="ui form" action="{% url 'detail_voter_post' video.id %}" method="post">
{% csrf_token %}
{% if user_ticker_for_this_video.choice == 'like' %}
<button class="ui red tiny button" type="submit" name="vote" value="normal">
<i class="icon checkmark"></i>Get it!
</button>
<button class="ui tiny button" type="submit" name="vote" value="dislike">
<i class="icon bomb"></i>Hmmm...
</button>
{% elif user_ticker_for_this_video.choice == 'dislike'%}
<button class="ui tiny button" type="submit" name="vote" value="like">
<i class="icon checkmark"></i>Get it!
</button>
<button class="ui red tiny button" type="submit" name="vote" value="normal">
<i class="icon bomb"></i>Hmmm...
</button> {% else %}
<button class="ui tiny button" type="submit" name="vote" value="like">
<i class="icon checkmark"></i>Get it!
</button>
<button class="ui tiny button" type="submit" name="vote" value="dislike">
<i class="icon bomb"></i>Hmmm...
</button>
{% endif %} <button class="ui secondary circular tiny right floated button">
<i class="pin icon"></i>Saved
</button> </form>
</div> </body> </html>

like 计数

    like_counts = Ticket.objects.filter(choice='like', video_id=page_num).count()  #视频有多少like
context['like_counts'] = like_counts
    <span style="color:#bbbbbb">{{ like_counts }} people got it</span>

12 debug

  • 只能adminuser完成投票功能
  • 匿名或者其他用户不能查看,投票

  

[项目2] 10mins的更多相关文章

  1. Fis3前端工程化之项目实战

    Fis3项目 项目目录结构: E:. │ .gitignore │ fis-conf.js │ index.html │ package.json │ README.md │ ├─material │ ...

  2. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  3. 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目

    最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...

  4. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  5. Travis CI用来持续集成你的项目

    这里持续集成基于GitHub搭建的博客为项目 工具: zqz@ubuntu:~$ node --version v4.2.6 zqz@ubuntu:~$ git --version git versi ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  8. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  9. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

随机推荐

  1. LVS Direct Routing 直接路由

    1. Direct Routing 直接路由 director分配请求到不同的real server, real server处理请求后直接回应给用户,这样director负载均衡器仅处理客户机与服务 ...

  2. 符号替换问题:请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

    public class Solution { public String replaceSpace(StringBuffer str) { String str1=str.toString(); c ...

  3. js之BOM和DOM

      今天我们来学习js中的一些基础的操作. 一.BOM对象 BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作.使用 BOM,开发者可以移动窗口.改变状态栏中的文本以及执行其他与页面内容不直接相 ...

  4. es6-Module 的加载实现

    浏览器加载 传统方法 在 HTML 网页中,浏览器通过<script>标签加载 JavaScript 脚本. <!-- 页面内嵌的脚本 --> <script type= ...

  5. H5如何做手机app(移动Web App)?图片轮播?ionic、MUI

    移动Web App 跨平台开发 用户不需要去卖场来下载安装App 任何时候都可以发布App只需要一个开发项目 可以使用HTML5,CSS3以及JavaScript以及服务器端语言来完成(PHP,Rub ...

  6. 菜鸟 学注册机编写之 “RSA”

    测试环境  系统: xp sp3 调试器 :od 1.10 RSA简单介绍 选取两个别人不知道的大素数p, q. 公共模n = p*q 欧拉值φ(n) = (p-1)(q-1) 选取公匙(加密匙) e ...

  7. 【Android开发笔记】杂项

    Android studio shift+enter : start new line Theme 将     <style name="AppBaseTheme" pare ...

  8. /etc/syslog.conf日志配置文件详解

    //将info或更高级别的消息送到/var/log/messages,除了mail以外. //其中*是通配符,代表任何设备:none表示不对任何级别的信息进行记录. *.info;mail.none; ...

  9. CSS第二节

    div做页面布局的建议 把整个网页从上到下分成若干块(一般分三块:头,中间,尾部),每一块都按下面的思路 先写第一层,可以设置背景色,或者高度和垂直居中(line-height保证内容不超出高度),不 ...

  10. VMware NAT端口映射外网访问虚拟机linux可能会出现的错误总结

    博主因为做实验报告的缘故,尝试以NAT的方式从外网远程连接到虚拟机的linux操作系统:https://www.cnblogs.com/jluzhsai/p/3656760.html,本文主要举出在此 ...