Python编程从入门到实践项目:Web应用程序
一、整体思维导图
1.整体总结
2.文件目录架构
每个应用的目录
二、django-bootstrap3演示有关地址的设置
bootstrap.py
文件位置:C:\python\learning_log\ll_env\Lib\site-packages\bootstrap3
后续设置样式的时候,代码没有问题,但是不显示效果,经查询是css和js地址需要修改为国内地址,还必须联通网络
--snip--
# Default settings
BOOTSTRAP3_DEFAULTS = {
"css_url": {
#"url": "https://stackpath.bootstrapcdn.com/bootstrap/3.4.1./css/bootstrap.min.css",
#换成国内地址
"url": "https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1./css/bootstrap.min.css",
"integrity": "sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1.+c8xmyTe9GYg1.l9a69psu",
"crossorigin": "anonymous",
},
"theme_url": None,
"javascript_url": {
#"url": "https://stackpath.bootstrapcdn.com/bootstrap/3.4.1./js/bootstrap.min.js",
#换成国内地址
"url": "https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1./js/bootstrap.min.js",
"integrity": "sha384-aJ21.OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd",
"crossorigin": "anonymous",
},
三、learning_log文件夹部分文件内容
1.settings.py
--snip--
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#第三方应用程序
'bootstrap3',
#我的应用--- 学习笔记 learning_log,users 两个应用
'learning_logs',
'users',
]
--snip--
#我的设置
LOGIN_URL = '/users/login/'
#django-bootstrap3的设置
BOOTSTRAP3 = {
'include_jquery':True,
}
--snip--
2.urls.py
"""
URL configuration for learning_log project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
1.. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1.. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1.. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('users/',include('users.urls',namespace='users')),
path('',include('learning_logs.urls',namespace='learning_logs')),
]
四、learning_logs文件夹文件内容
1.modes.py
相当于定了数据库中表及其字段信息,是一个类,定义了属性和方法
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Topic(models.Model):
"""用户学习的主题"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
"""返回模型的字符串表示"""
return self.text
class Entry(models.Model):
"""学到的有关某个主题的详细内容"""
#从django1..9开始ForeignKey中on_delete参数是必须的
topic = models.ForeignKey(Topic,on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entrie'
def __str__(self):
"""返回模型的字符串表示"""
return self.text[:50]+"..."
2.urls.py
""" 定义learnling_logs的url模式"""
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns =[
# 主页
path('',views.index,name='index'),
#显示所有的主题
path('topics/',views.topics,name='topics'),
#显示特定主题的详细页面path(r'topics/(?P<topic_id>\d+)/$/',views.topic,name='topic'),
path( 'topics/<int:topic_id>/',views.topic,name='topic'),
#用于添加新主题的网页
path('new_topic/',views.new_topic,name='new_topic'),
#在特定的主题下添加新条目
path('new_entry/<int:topic_id>/',views.new_entry,name='new_entry'),
#编辑条目
path('edit_entry/<int:entry_id>/',views.edit_entry,name='edit_entry'),
]
3、forms.py
只包含一个内嵌的Meta类,他告诉Django根据哪个模型创建表单,以及在表单中包含哪些字段。
from django import forms
from .models import Topic,Entry
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text':''}
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels ={'text':''}
widgets = { 'text':forms.Textarea(attrs={'cols':80})}
3.views.py
接受请求信息,准备数据处理,并发给浏览器
基本每一个函数代表一个动作
from django.shortcuts import render
from django.http import HttpResponseRedirect,Http404
from django.urls import reverse # django.core.urlresolverses django2.0 修改为django.urls
from django.contrib.auth.decorators import login_required
from .models import Topic,Entry
from .forms import TopicForm,EntryForm
# Create your views here.
def index(request):
""" 学习笔记的主页"""
return render(request,'learning_logs/index.html')
@login_required
def topics(request):
"""显示所有的主题"""
topics = Topic.objects.filter(owner=request.user).order_by('date_added')
context = {'topics':topics}
return render(request,'learning_logs/topics.html',context)
@login_required
def topic(request,topic_id):
"""显示特定主题及主题下的所有条目"""
topic = Topic.objects.get(id=topic_id)
#确认请求的主题属于当前用户
if topic.owner !=request.user:
raise Http404
# -表示按降序排列
entries = topic.entry_set.order_by('-date_added')
context = {'topic':topic,'entries':entries}
return render(request,'learning_logs/topic.html',context)
@login_required
def new_topic(request):
#添加新主题
if request.method !='POST':
#未提交数据,创建一个新表单
form = TopicForm()
else:
#POSt提交的数据,对数据进行处理
form =TopicForm(request.POST)
if form.is_valid():
new_topic = form.save(commit=False)
new_topic.owner = request.user
new_topic.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form':form}
return render(request,'learning_logs/new_topic.html',context)
@login_required
def new_entry(request,topic_id):
#在特定的主题中添加新条目
topic = Topic.objects.get(id=topic_id)
if request.method != 'POST':
#未提交数据,创建一个新表单
form = EntryForm()
else:
#post提交的额数据,对数据进行处理
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic_id]))
context = {'topic':topic,'form':form}
return render(request,'learning_logs/new_entry.html',context)
@login_required
def edit_entry(request,entry_id):
"""编辑既有条目"""
entry = Entry.objects.get(id=entry_id)
topic = entry.topic
#确认请求的主题属于当前用户
if topic.owner !=request.user:
raise Http404
if request.method != 'POST':
#未提交数据,创建一个新表单
form = EntryForm(instance=entry)
else:
#post提交的额数据,对数据进行处理
form = EntryForm(instance=entry,data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
context = {'entry':entry,'topic':topic,'form':form}
return render(request,'learning_logs/edit_entry.html',context)
4.下级templates\learning_logs文件夹及相关内容
4.1base.html
模版文件夹,使用bootstrap3设置样式
{% load bootstrap3 %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title> 学习笔记--lxy </title>
{% bootstrap_css %}
{% bootstrap_javascript %}
</head>
<body>
<!-- Static navbar -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
</button>
<a class="navbar-brand" href="{% url 'learning_logs:index' %}">
学习笔记 </a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="{% url 'learning_logs:topics' %}">Topics</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li><a> Hello,{{ user.username }}.</a></li>
<li><a href="{% url 'users:logout' %}"> log out </a></li>
{% else %}
<li><a href="{% url 'users:register' %}">register</a></li>
<li><a href="{% url 'users:login' %}">log in</a></li>
{% endif %}
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<div class="page-header">
{% block header %}{% endblock header %}
</div>
<div>
{% block content %}{% endblock content %}
</div>
</div><!-- /container -->
</body>
</html>
4.2index.html
{% extends "learning_logs/base.html" %}
{% block header %}
<div class="jumbotron">
<h1>Track your learning.</h1>
</div>
{% endblock header %}
{% block content %}
<h2>
<a href="{% url 'users:register' %}">Register an account </a> to make
your own learning Log,and list the topics you're learning about.
</h2>
<h2>
Whenever you learn something new about a topic,make an entry
summarizing what you're learned.
</h2>
{% endblock content %}
4.3topics.html
{% extends "learning_logs/base.html" %}
{% block header %}
<h1> Topics</h1>
{% endblock header %}
{% block content %}
<ul>
{% for topic in topics %}
<li>
<h3>
<a href="{% url 'learning_logs:topic' topic.id %}"> {{ topic }} </a>
</h3>
</li>
{% empty %}
<li>No topics have been added yes.</li>
{% endfor %}
</ul>
<h3><a href="{% url 'learning_logs:new_topic' %}"> Add a new topic: </a></h3>
{% endblock content %}
4.4topic.html
{% extends "learning_logs/base.html" %}
{% block header %}
<h2> {{ topic }} </h2>
{% endblock header %}
{% block content %}
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}"> add new entry </a>
</p>
{% for entry in entries %}
<div class="panel panel-default">
<div class="panel-heading">
<h3>
{{ entry.date_added|date:'M d,Y h:i' }}
<small>
<a href="{% url 'learning_logs:edit_entry' entry.id %}"> edit entry</a>
</small>
</h3>
</div>
<div class="panel-body">
{{ entry.text|linebreaks }}
</div>
</div> <!-- panel -->
{% empty %}
There are no entries for this topic.
{% endfor %}
{% endblock content %}
4.4new_topic.html
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
{% block header %}
<h2> Add a new topic:</h2>
{% endblock header %}
{% block content %}
<form action="{% url 'learning_logs:new_topic'%}" method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button name="submit" class="btn btn-primary">add topic </button>
{% endbuttons %}
</form>
{% endblock content %}
4.5new_entry.html
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
{% block header %}
<h2><a href="{% url 'learning_logs:topic' topic.id %}"> {{ topic }} </a></h2>
<h2> Add a new entry:</h2>
{% endblock header %}
{% block content %}
<form action="{% url 'learning_logs:new_entry' topic.id %}" method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button name="submit" class="btn btn-primary">add entry </button>
{% endbuttons %}
</form>
{% endblock content %}
4.6edit_entry.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p><a href="{% url 'learning_logs:topic' topic.id %}"> {{ topic }} </a></p>
<p>Edit Entry:</p>
<form action="{% url 'learning_logs:edit_entry' entry.id %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">save changes</button>
</form>
{% endblock content %}
五、users文件夹下相关内容
1.urls.py
""" 为users应用程序定义url模式"""
from django.urls import path
#使用django提供的默认登录视图
from django.contrib.auth.views import LoginView
from . import views
app_name = 'users'
LoginView.template_name='users/login.html'
urlpatterns = [
#登录页面
path('login/',LoginView.as_view(),name='login'),
#注销页面
path('logout/',views.logout_view,name='logout'),
#注册页面
path('register/',views.register,name='register'),
]
2.views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse # django.core.urlresolverses django2.0 修改为django.urls
from django.contrib.auth import logout,login,authenticate
from django.contrib.auth.forms import UserCreationForm
# Create your views here.
def logout_view(request):
"""注销用户"""
logout(request)
return HttpResponseRedirect(reverse('learning_logs:index'))
def register(request):
"""注册新用户"""
if request.method != 'POST':
#显示空的注册表单
form = UserCreationForm()
else:
#处理填写的表单
form = UserCreationForm(data=request.POST)
if form.is_valid():
new_user =form.save()
#让用户自动登录,并重定向到主页
authenticated_user = authenticate(username =new_user.username,password=request.POST['password1'])
login(request,authenticated_user)
return HttpResponseRedirect(reverse('learning_logs:index'))
context={'form':form}
return render(request,'users/register.html',context)
3.templates\users文件夹下相关文件
3.1login.html
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
{% block header %}
<h2> Log in to your account.</h2>
{% endblock header %}
{% block content %}
{% if form.errors %}
<p> Your username or password didn't match .Please try again. </p>
{% endif%}
<form method="post" action="{% url 'users:login' %}" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button name="submit" class="btn btn-primary"> log in </button>
{% endbuttons %}
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
3.2register.html
{% extends "learning_logs/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:register' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit"> register</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
}
{% bootstrap_form form %}
{% buttons %}
<button name="submit" class="btn btn-primary"> log in </button>
{% endbuttons %}
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
{% endblock content %}
#### 3.2register.html
```html
{% extends "learning_logs/base.html" %}
{% block content %}
<form method="post" action="{% url 'users:register' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit"> register</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}