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"), ]
效果图