forth_Stark之link_modelform_添加编辑删除_Django分页器
效果

1.Stark这list_display_link:
# sites 里: # 默认配置类加上 list_display_links = [] # 点击书名等也可以进行编辑 ''' 然后在下面的添加数据里,先判断是否有自定制的list_display_links = [], 如果有,则按照列表里需要带超链接的字体,从原来的单纯添加数据改为添加a标签 ''' else: # 所有对象空间如果有属性值,利用以下方法即可反射获取值 val = getattr(obj, field_or_func) if field_or_func in self.list_display_links: # 如果有自定制link方法,则走下面这条语句,obj则是当前表的该条对象,link方法完成 val = mark_safe("<a href='%s'>%s</a>" % (self.get_change_url(obj), val))
2.modelform:
# sites models_form_class = None # 设定默认使用默认模板,进行添加编辑业务数据显示及添加修改 def get_model_form(self): from django.forms import ModelForm # 导入ModelForm模块,即将model 转化成form 的组件 # 设定默认模板 class BaseModelForm(ModelForm): # 设定默认模板,其中__all__ class Meta: model = self.model # 告诉ModelForm是关联哪张表 fields = "__all__" # 展示全部数据字段 # 如果没有自定制则返回默认展示方式 return self.models_form_class or BaseModelForm def add_view(self, request): base_model_form = self.get_model_form() # 获取当前展示字段 if request.method == "GET": form_obj = base_model_form() # 获取当前展示字段并传到前端 return render(request, 'stark/add_view.html', locals()) else: form_obj = base_model_form(request.POST) if form_obj.is_valid(): # 判断用户输入的值是否符合model的规定 form_obj.save() # 如果符合则保存到数据库,并返回查看页面 return redirect(self.get_list_url()) else: return render(request, "stark/add_view.html", locals()) # 否则将携带报错信息的form返回当前页面提示用户 def list_view: #添加以下数据,将addurl传到前端 table_name = self.model._meta.verbose_name # 当前表的名字 add_url = self.get_add_url() # 将add_url定义,此时local就会自动传到前端 return render(request, 'stark/list_view.html', locals())
# add_view.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <style> input,select{ display: block; width: 100%; height: 34px; padding: 6px 12px; font-size: 14px; line-height: 1.42857143; color: #555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 4px; } .error{ color: red; } </style> </head> <body> <h3> 添加数据 </h3> {% include "stark/form.html" %} </body> </html>
# form.html <div class="container"> <div class="row"> <div class="col-md-8"> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form_obj %} <div class="form-group"> <label for="">{{ field.label }}</label> {{ field }} <span class="error pull-right">{{ field.errors.0 }}</span> </div> {% endfor %} <button class="btn btn-default">submit</button> </form> </div> </div> </div>
此时添加页面完成
# sites
def change_view(self, request, id): base_model_form = self.get_model_form() # 获取需要展示字段 edit_obj = self.model.objects.filter(pk=id).first() if request.method == 'GET': form_obj = base_model_form(instance=edit_obj) # 这句话让modelform可以显示valus内容以供编辑 return render(request, 'stark/change_view.html', locals()) else: form_obj = base_model_form(request.POST, instance=edit_obj) # instance 是告诉modelform是编辑,且编辑哪个对象 if form_obj.is_valid(): form_obj.save() return redirect(self.get_list_url()) else: return render(request, 'stark/change_view.html', locals())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <style> input,select{ display: block; width: 100%; height: 34px; padding: 6px 12px; font-size: 14px; line-height: 1.42857143; color: #555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 4px; } .error{ color: red; } </style> </head> <body> <h3> 编辑数据 </h3> {% include "stark/form.html" %} </body> </html>
此时编辑功能也已完成
# sites def delete_view(self, request, id): if request.method == 'POST': print(2222) self.model.objects.filter(pk=id).delete() return redirect(self.get_list_url()) # 不删除则返回 print(1111) list_url = self.get_list_url() return render(request, 'stark/delete_view.html', locals())
# delete_view.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> </head> <body> <form action="" method="post"> {% csrf_token %} <a href="{{ list_url }}" class="btn btn-warning">取消</a> <input type="submit" class="btn btn-danger" value="确认删除"> </form> </body> </html>
此时删除页面也完成
3.知识点补充关于神奇组件ModelForm
from django.forms import ModelForm from django.forms import widgets as wid class StudentList(ModelForm): class Meta: model = models.Student #对应的Model中的类 fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段 exclude = None #排除的字段 labels = None #提示信息 help_texts = None #帮助提示信息 widgets = None #自定义插件 error_messages = None #自定义错误信息 #error_messages用法: error_messages = { 'name':{'required':"用户名不能为空",}, 'age':{'required':"年龄不能为空",}, } #widgets用法,比如把输入用户名的input框给为Textarea #首先得导入模块 from django.forms import widgets as wid #因为重名,所以起个别名 widgets = { "name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性 } #labels,自定义在前端显示的名字 labels= { "name":"用户名" }
# 补充 aria-label属性用来给当前元素加上的标签描述,接受字符串作为参数。
是用不可视的方式给元素加label(如果被描述元素存在真实的描述元素,
可使用 aria-labelledby 属性作为来绑定描述元素和被描述元素来代替)
4.Django分页
# views
from django.shortcuts import render, HttpResponse, redirect from app01.models import Book # 导入Book # Create your views here. def index(request): """ book_list = [] for i in range(1, 101): # 将所有数据添加到list book = Book(title="book_%s" % i, price=i*i) book_list.append(book) Book.objects.bulk_create(book_list) :param request: :return: """ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger book_list = Book.objects.all() paginator = Paginator(book_list, 5) # 5条信息一页 current_page = int(request.GET.get('page', 1)) # 获取page的数字,默认1 # print(current_page, paginator.num_pages) if current_page > paginator.num_pages: # 如果搜索页数大于页数,则返回第一页 current_page = 1 if paginator.num_pages > 12: if current_page - 5 < 1: # 如果当前页数减5小于1 sf_page_range = range(1, 11) # 页码的列表为1-11内 elif current_page + 5 > paginator.num_pages: # 如果当前页数加5大于总页数 sf_page_range = range(current_page - 5, paginator.num_pages + 1) # 页码在-5,和最大值之间 else: sf_page_range = range(current_page - 5, current_page + 5) # 不大又不小,则执行该条语句 else: # 如果没有分到12页,则执行以下语句 sf_page_range = paginator.page_range try: page = paginator.page(current_page) # 移动到该分页 except EmptyPage as e: # 如果没有该页数则指向以下语句 page = paginator.page(1) return render(request, 'index.html', locals())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- 可选的 Bootstrap 主题文件(一般不用引入) --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </head> <body> <h3>大大的标题</h3> <ul> {% for book in page %} <li> {{ book }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="?page=1"> <span aria-label="true">首页</span> </a> </li> {% if page.has_previous %} {# 判断是否有该页#} <li> <a href="?page={{ page.previous_page_number }}" aria-label="previous"> <span aria-hidden="true">上一页</span> </a> </li> {% else %} <li class="disabled"> <a href="#" aria-label="previous"> <span aria-hidden="true">上一页</span> </a> </li> {% endif %} {% for num in sf_page_range %} {% if current_page == num %} <li class="active"><a href="?page={{ num }}">{{ num }}</a></li> {% else %} <li><a href="?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if page.has_next %} {# 判断是否有该页#} <li> <a href="?page={{ page.next_page_number }}" aria-label="Nex"> <span aria-hidden="true">下一页</span> </a> </li> {% else %} <li class="disabled"> <a href="#" aria-label="Next"> <span aria-hidden="true">下一页</span> </a> </li> {% endif %} <li> <span> <input type="text" id="text_id" style="height: 20px;width: 40px"> </span> </li> <li> <a href="?page=1" id="search_id"> <span aria-label="true">搜索</span> </a> </li> </ul> </nav> <script> $("#text_id").on("blur", function () { num = $("#text_id").val(); let a_obj = document.getElementById("search_id"); a_href = "?page=" + num; a_obj.href = a_href; }) </script> </body> </html> {#现代的辅助技术能够识别并朗读由 CSS 生成的内容和特定的 Unicode 字符。#} {#为了避免 屏幕识读设备抓取非故意的和可能产生混淆的输出内容(尤其是当图标纯粹作为装饰用途时),#} {#我们为这些图标设置了 aria-hidden="true" 属性#}
# urls from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), ]
以上



浙公网安备 33010602011771号