stark——增删改页面

一、制作添加页面

1、前置准备

(1)修改增删改的视图函数名

class ModelStark(object):

    def add_view(self, request):
        return HttpResponse("add")

    def delete_view(self, request, id):
        return HttpResponse("delete")

    def change_view(self, request, id):
        return HttpResponse("change")

(2)调整路由对应的视图函数

class ModelStark(object):

    def get_urls_2(self):
        temp = []

        # 用name取别名app名+model名+操作名可以保证别名不会重复
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        temp.append(url(r"^add/", self.add_view, name="%s_%s_add" % (app_label, model_name)))
        temp.append(url(r"^(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (app_label, model_name)))
        temp.append(url(r"^(\d+)/change/", self.change_view, name="%s_%s_change" % (app_label, model_name)))
        temp.append(url(r"^$", self.list_view, name="%s_%s_list" % (app_label, model_name)))
        return temp

(3)在查看页面添加add按钮

  首先在list_view中获取add_url:

class ModelStark(object):
    '''代码省略'''
    def get_add_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_add" % (app_label, model_name))
        return _url

    def list_view(self, request):
        '''代码省略'''
        # 构建一个查看url
        add_url = self.get_add_url()

        return render(request, "list_view.html", locals())

  在list_view.html中添加“添加数据”按钮:

<body>
<h4>数据列表</h4>
<div class="container">
    <div class="row">
        <div class="col-md-9">
            {# <a href="add/" class="btn btn-primary">添加数据</a> #}
            <a href="{{ add_url }}" class="btn btn-primary">添加数据</a>
    """代码省略"""
</body>
</html>

(4)重构模型

  由于之前的表结构过于简单,在进行添加操作时很多问题无法发现,在这里重新构造模型(一对一、一对多、多对多都有)。

from django.db import models


# Create your models here.


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 与AuthorDetail建立一对一的关系
    authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)

    def __str__(self):
        return self.name


class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)

    def __str__(self):
        return self.telephone


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)

    # 与Publish建立一对多的关系,外键字段建立在多的一方
    publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors = models.ManyToManyField(to='Author', )

    def __str__(self):
        return self.title
app01/models.py

 

  同时将app01/admin.py和app01/stark.py中的内容清空重新进行构建。

(5)删除数据重新进行数据库迁移

  1)删除app01/migrations/下的文件

  2)删除db.sqlite3

  3)数据迁移

manage.py@stark_demo > makemigrations
manage.py@stark_demo > migrate

(6)在stark中注册表:

app01/stark.py:

from stark.service.stark import site, ModelStark
from django.utils.safestring import mark_safe
from django.urls import reverse
from .models import *

site.register(Book)
site.register(Publish)
site.register(Author)
site.register(AuthorDetail)

  到此页面已经可以正常访问:

  

2、自定制配置modelform来构建添加页面

class ModelStark(object):
    def add_view(self, request):
        from django.forms import ModelForm
        from django.forms import widgets as wid

        class ModelFormDemo(ModelForm):
            class Meta:
                model = self.model
                fields = "__all__"
                # 不能使用这种方法,因为每个表的字段是不同的
                # widgets = {
                #     "title": wid.TextInput(attrs={"class": "form-control"})
                # }
        form = ModelFormDemo()  # 实例化
        return render(request, "add_view.html", locals())

3、构建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">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <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;
            -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
            box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
            -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
            -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
            transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
        }
    </style>
</head>
<body>
<h3>添加页面</h3>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post">
                {% for field in form %}
                    <div>
                        <label for="">{{ field.label }}</label>
                        {{ field }}
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-default">提交</button>
            </form>
        </div>
    </div>
</div>
</body>
</html>
View Code

  由于每个表字段不同,因此不能使用wigets来给所有标签添加form-control样式,直接在页面用css给input\select构建form-control的样式。

  显示效果如下所示:

  

4、给所有字段更换为中文

class ModelStark(object):
    """默认类,定制配置类"""
    list_display = ["__str__",]
    list_display_links = []
    modelform_class = []

    '''代码省略'''

    def get_modelform_class(self):
        """用来获取modelform类"""
        if not self.modelform_class:
            # 如果没有值
            from django.forms import ModelForm
            from django.forms import widgets as wid

            class ModelFormDemo(ModelForm):
                class Meta:
                    model = self.model
                    fields = "__all__"

            return ModelFormDemo
        else:
            # 如果有值说明在用户已经自己定制过了,直接取值
            return self.modelform_class

    def add_view(self, request):
        ModelFormDemo = self.get_modelform_class()
        form = ModelFormDemo()  # 实例化
        return render(request, "add_view.html", locals())

(1)定义get_modelform_class方法来获取modelform类。如果在app01/stark.py中自定义配置类没有modelform_class,则默认为空,通过这个方法来获取modelform。

(2)自定义配置Book类,并将字段显示中文 

from stark.service.stark import site, ModelStark
from .models import *
from django.forms import ModelForm

class BookModelForm(ModelForm):
    class Meta:
        model = Book
        fields = "__all__"

        labels = {
            "title": "书籍名称",
            "publishDate": "出版日期",
            "price": "价格",
            "publish": "出版社",
            "authors": "作者"
        }

class BookConfig(ModelStark):
    list_display = ["title", "price", "publishDate"]
    modelform_class = BookModelForm

site.register(Book, BookConfig)

(3)显示效果:

  

5、添加信息提交

(1)add_view视图函数中处理post请求:

class ModelStark(object):
    def add_view(self, request):
        ModelFormDemo = self.get_modelform_class()
        if request.method == "POST":
            form = ModelFormDemo(request.POST)
            if form.is_valid():  # 校验字段全部合格
                form.save()
                return redirect(self.get_list_url())  # 跳转到当前访问表的查看页面

            # (精髓)校验有错误返回页面,且包含了错误信息
            return render(request, "add_view.html", locals())

        form = ModelFormDemo()  # 实例化
        return render(request, "add_view.html", locals())

  注意校验通过跳转到当前访问表的查看页面;校验不通过返回添加页面,且包含错误信息。

(2)add_view.html在提交报错时显示错误信息

<style>
    input,select {
        /*代码省略*/
    }
    .error {
        color: red;
    }
</style>

<body>
<h3>添加页面</h3>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div>
                        <label for="">{{ field.label }}</label>
                        {{ field }} <span class="error pull-right">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-default pull-right">提交</button>
            </form>
        </div>
    </div>
</div>
</body>

(3)提交显示效果如下所示:

  

  

二、制作编辑页面

  编辑页面视图和模板都与添加页面非常相似。

1、change_view视图编写

class ModelStark(object):

    def change_view(self, request, id):
        """编辑视图"""
        ModelFormDemo = self.get_modelform_class()
        # 编辑对象
        edit_obj = self.model.objects.filter(pk=id).first()

        if request.method == "POST":
            form = ModelFormDemo(request.POST, instance=edit_obj)  # instance就是给这个记录更改为最新的数据
            if form.is_valid():  # 校验字段全部合格
                form.save()
                return redirect(self.get_list_url())  # 跳转到当前访问表的查看页面

            # (精髓)校验有错误返回页面,且包含了错误信息
            return render(request, "add_view.html", locals())

        form = ModelFormDemo(instance=edit_obj)   # 用instance放入编辑对象就有了编辑数据

        return render(request, "change_view.html", locals())

  这里最大的区别就是获取了当前的编辑对象,使用instance放入编辑对象获取编辑数据;同时在post请求中将记录更新为最新的数据。

  这里是直接把add_view.html复制了一份做成了change_view.py,修改效果如下所示:

  

2、{% include 'form.html' %}优化代码重复

创建一个form.html:

<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div>
                        <label for="">{{ field.label }}</label>
                        {{ field }} <span class="error pull-right">{{ field.errors.0 }}</span>
                    </div>
                {% endfor %}
                <button type="submit" class="btn btn-default pull-right">提交</button>
            </form>
        </div>
    </div>
</div>

add_view.html和change_view.html的body部分修改如下:

<body>
<h3>编辑页面</h3>
{% include 'form.html' %}
</body>

三、制作删除页面

  删除时不要直接删除,需要提示确认。

class ModelStark(object):

    def delete_view(self, request, id):
        url = self.get_list_url()
        if request.method == "POST":
            self.model.objects.filter(pk=id).delete()
            return redirect(url)

        # self.model.objects.filter(pk=id).delete()
        return render(request, "delete_view.html", locals())

  一个form表单里面只能有一个请求按钮,因此确认删除是按钮,取消是一个a标签跳转到查看页面。

  delete_view.html:

<body>
<h3>删除页面</h3>

<form action="" method="post">
    {% csrf_token %}
    <button>确认删除?</button>
    <a href="{{ url }}">取消</a>
</form>
</body>

  执行效果:

  

  确认后显示效果如下:

  

 

posted @ 2018-08-21 14:18  休耕  阅读(446)  评论(0编辑  收藏  举报