1. 与LIstView不同
LIstView是获取一个表的内容,或一个表的部分内容
DetailView是获取一个条内容,所以这样知道要拿哪一条数据呢,就需要通过primary key(pk)
在template/personal_info目录下创建person_detail.html文件
# first_project/personal_info/views.py from django.urls import reverse, reverse_lazy from django.views import View from django.views.generic import ListView, CreateView, DetailView from personal_info.forms import PersonCreateForm from personal_info.models import Person class PersonList(ListView): model = Person template_name = 'personal_info/person_list.html' # 会直接上templates目录下找 def get_context_data(self, *, object_list=None, **kwargs): context = super().get_context_data(object_list=object_list, **kwargs) # 先把父类的context拿到 context.update({'list': [1.23, 2.34, 3.45]}) return context class PersonCreate(CreateView):# 注意这里改成了CreateView # 需要定义以下四个变量 form_class = PersonCreateForm model = Person template_name = 'personal_info/person_create.html' success_url = reverse_lazy('personal_info:person_list') class PersonDetail(DetailView): model = Person template_name = 'personal_info/person_detail.html'
# first_project/personal_info/urls.py from django.urls import path from personal_info import views app_name = 'personal_info' urlpatterns = [ # name值就是用来html中请求的url,会进行拼接,例如:personal_info:person_list path('', views.PersonList.as_view(), name="person_list"), path('create/', views.PersonCreate.as_view(), name="person_create"), # pk是DetailView中的pk_url_kwarg path('<int:pk>/', views.PersonDetail.as_view(), name="person_detail"), ]
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %} <!-- 导入自定义tag -->
{% block title_content %}疫情人员登记表{% endblock %}
{% block body_content %}
<table class="table">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">名字</th>
<th scope="col">年龄</th>
<th scope="col">性别</th>
<th scope="col">疑似</th>
</tr>
</thead>
<tbody>
{{ list|add_filter }} <!-- 调用自定义filter -->
{% add_tag list %} <!-- 调用自定义tag -->
<!-- 默认是object_list 模板语言for循环语法 -->
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td><a href="{% url 'personal_info:person_detail' item.pk %}">{{ item.name }}</a></td>
<td>{{ item.age }}</td>
<!-- 不加get_display会显示数字 -->
<td>{{ item.gender|yesno:"男,女"}}</td>
<td>{% if item.temperature > 37 %}是{% else %}否{% endif %}</td>
</tr>
{% empty %}
<tr>
<!-- 意思是将5列合并成1列 -->
<td colspan="5">暂无数据</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- 这个地方跳转到 personal_info:person_create url -->
{% endblock %}
启动服务效果
点击名字后->
2.DeleteView和UpdateView
都是对一条数据进行操作的,所以需要传pk
personal_info项目主要代码:
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %}
{% block title_content %}修改{{ object.name }}的信息{% endblock %} <!--object就是查出来的person-->
{% block body_content %}
<form action="{% url 'personal_info:person_update' object.pk %}" method="post"> <!--如果是前后端分离,这里要改为put请求-->
{% csrf_token %}
{% for item in form %}
<div class="col-md-6 mb-3">
{{ item|label_class:"form-label" }}
{{ item }}
{{ item.errors}}
</div>
{% endfor %}
<p><button type="submit" class="btn btn-primary">保存</button></p>
</form>
{% endblock %}
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %} <!-- 导入自定义tag -->
{% block title_content %}疫情人员登记表{% endblock %}
{% block body_content %}
<table class="table">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">名字</th>
<th scope="col">年龄</th>
<th scope="col">性别</th>
<th scope="col">疑似</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{{ list|add_filter }} <!-- 调用自定义filter -->
{% add_tag list %} <!-- 调用自定义tag -->
<!-- 默认是object_list 模板语言for循环语法 -->
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td><a href="{% url 'personal_info:person_detail' item.pk %}">{{ item.name }}</a></td>
<td>{{ item.age }}</td>
<!-- 不加get_display会显示数字 -->
<td>{{ item.gender|yesno:"男,女"}}</td>
<td>{% if item.temperature > 37 %}是{% else %}否{% endif %}</td>
<td><a class="btn btn-sm btn-outline-success" href="{% url 'personal_info:person_update' item.pk %}">更新</a></td>
</tr>
{% empty %}
<tr>
<!-- 意思是将5列合并成1列 -->
<td colspan="5">暂无数据</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- 这个地方跳转到 personal_info:person_create url -->
<p><a href="{% url 'personal_info:person_create' %}" class="btn btn-primary">登记</a></p>
{% endblock %}
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %}
{% block title_content %}{{ object.name }}的信息{% endblock %} <!--object就是查出来的person-->
{% block body_content %}
<div class="card {% if object.temperature > 37 %}text-white bg-danger"{% endif %} style=" 18rem;">
<div class="card-body">
<h5 class="card-title">{{ object.name }}的信息</h5>
<p class="card-text">
<span class="badge rounded-pill bg-info text-dark">年龄:{{ object.age }}岁</span>
<span class="badge rounded-pill bg-info text-dark">性别:{{ object.gender|yesno:'男,女' }}</span>
</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">身份证:{{ object.id_card }}</li>
<li class="list-group-item">住址:{{ object.address }}</li>
</ul>
<div class="card-body">
<a href="{% url 'personal_info:person_update' object.pk %}" class="card-link">编辑</a>
<a href="{% url 'personal_info:person_delete' object.pk %}" class="card-link">删除</a>
<a class="card-link" href="{% url 'personal_info:person_list' %}">返回</a>
</div>
</div>
{% endblock %}
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %}
{% block title_content %}删除{{ object.name }}的信息{% endblock %} <!--object就是查出来的person-->
{% block body_content %}
<div class="col-4">
<div class="alert-danger mb-3">是否删除{{ object.name }}的信息</div>
<form action="{% url 'personal_info:person_delete' object.pk %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">删除</button>
</form>
</div>
{% endblock %}
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %}
{% block title_content %}登记人员信息{% endblock %}
{% block body_content %}
<form action="{% url 'personal_info:person_create' %}" method="post">
{% csrf_token %}
{% for item in form %}
<div class="col-md-6 mb-3">
{{ item|label_class:"form-label" }}
{{ item }}
{{ item.errors}}
</div>
{% endfor %}
<p><button type="submit" class="btn btn-primary">保存</button></p>
</form>
{% endblock %}
{% extends 'personal_info/base.html' %} <!-- 引入基础模版 -->
{% load mytags %}
{% block title_content %}登记人员信息{% endblock %}
{% block body_content %}
<form action="{% url 'personal_info:person_create' %}" method="post">
{% csrf_token %}
{% for item in form %}
<div class="col-md-6 mb-3">
{{ item|label_class:"form-label" }}
{{ item }}
{{ item.errors}}
</div>
{% endfor %}
<p><button type="submit" class="btn btn-primary">保存</button></p>
</form>
{% endblock %}
# first_project/personal_info/models.py from django.db import models # Create your models here. from django.db import models class Person(models.Model): # 继承Model GENDER_CHOICES = ( (1, '男'), (0, '女'), ) name = models.CharField(max_length=32) # 定义VARCHAR类型字段,max_length是必须的 age = models.IntegerField() # 定义整形字段 gender = models.BooleanField(choices=GENDER_CHOICES) # 定义布尔类型变量,可选择的 id_card = models.CharField(max_length=18) address = models.CharField(max_length=256) temperature = models.FloatField() # 定义浮点型字段 class Meta: # model中的配置中心 permissions = () # 将数据库权限设置为空
# first_project/personal_info/forms.py from django import forms from personal_info.models import Person class PersonCreateForm(forms.ModelForm): class Meta: # 配置中心,前端的东西都可以在这里修改,比如css,需要的时候再查一下就可以 model = Person # 把model导进来 fields = '__all__' # 代表所有字段,也可以挨个写一下 widgets = { 'name': forms.TextInput(attrs={'id': 'name_id', 'class': 'form-control'}), # 可以开发模式打开网页,找到name那行,看到新加了id的字段 'gender': forms.Select(attrs={'id': 'gender_id', 'class': 'form-select'}), 'age': forms.NumberInput(attrs={'id': 'age_id', 'class': 'form-control'}), 'address': forms.TextInput(attrs={'id': 'address_id', 'class': 'form-control'}), 'id_card': forms.TextInput(attrs={'id': 'id_card_id', 'class': 'form-control'}), 'temperature': forms.NumberInput(attrs={'id': 'temperature_id', 'class': 'form-control', 'step': '0.1'}), } labels = { # labels没办法在这里加class, 通过filter去做 'name': '名字' # 可以看到页面中的原本英文'name'变成了'名字' } # 直接用PersonCreateForm就可以 class PersonUpdateForm(PersonCreateForm): pass class PersonDeleteForm(PersonCreateForm): pass
# first_project/personal_info/templatetags/mytags.py from functools import reduce from django import template register = template.Library() # register的名字是固定的,不可改变 @register.filter(is_safe=False) def add_filter(value, rounded=2): assert isinstance(value, list) return round(sum(value), rounded) @register.simple_tag # 官方推荐方式 def add_tag(*args, **kwargs): args = args[0] assert isinstance(args, list) result = reduce(lambda x, y: x + y, args) rounded = kwargs.get('rounded') or 2 result = round(result, rounded) return result @register.filter(is_safe=False) def label_class(value, cls): # 为了改label加class return value.label_tag(attrs={'class': cls})
# first_project/personal_info/views.py from django.http import HttpResponseRedirect from django.shortcuts import render # Create your views here. from django.urls import reverse, reverse_lazy from django.views import View from django.views.generic import ListView, CreateView, DetailView, UpdateView, DeleteView from personal_info.forms import PersonCreateForm, PersonUpdateForm from personal_info.models import Person class PersonList(ListView): model = Person template_name = 'personal_info/person_list.html' # 会直接上templates目录下找 def get_context_data(self, *, object_list=None, **kwargs): context = super().get_context_data(object_list=object_list, **kwargs) # 先把父类的context拿到 context.update({'list': [1.23, 2.34, 3.45]}) return context class PersonCreate(CreateView): # 注意这里改成了CreateView # 需要定义以下四个变量 form_class = PersonCreateForm model = Person template_name = 'personal_info/person_create.html' success_url = reverse_lazy('personal_info:person_list') class PersonDetail(DetailView): model = Person template_name = 'personal_info/person_detail.html' # update用到的属性和create一样 class PersonUpdate(UpdateView): model = Person template_name = 'personal_info/person_update.html' form_class = PersonUpdateForm #这里就是用来form验证的,所以detail和delete不需要用 success_url = reverse_lazy('personal_info:person_list') class PersonDelete(DeleteView): model = Person success_url = reverse_lazy('personal_info:person_list') template_name = 'personal_info/person_delete.html'
# first_project/personal_info/urls.py from django.urls import path from personal_info import views app_name = 'personal_info' urlpatterns = [ # name值就是用来html中请求的url,会进行拼接,例如:personal_info:person_list path('', views.PersonList.as_view(), name="person_list"), path('create/', views.PersonCreate.as_view(), name="person_create"), # pk是DetailView中的pk_url_kwarg path('<int:pk>/', views.PersonDetail.as_view(), name="person_detail"), path('<int:pk>/update/', views.PersonUpdate.as_view(), name="person_update"), path('<int:pk>/delete/', views.PersonDelete.as_view(), name="person_delete"), ]
效果图

