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="width: 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"), ]
效果圖