原生Form 和 Form组件 Modelform

Posted rivend

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生Form 和 Form组件 Modelform相关的知识,希望对你有一定的参考价值。

主要的文件:manage.py,url.py,views.py,settings.py,models.py

  manage.py:项目管理文件,一般不做修改。

  url.py:路由系统,配置views.py中函数和对应路径的关系。

  views.py:添加视图函数,常见的增删查改函数。

  settings.py:模板配置文件,对TEMPLATES 、DATABASES、STATIC_URL 等进行配置。

  models.py:数据库相关表的类描述。

Django基础必备三件套:HttpResponse, render, redirect

  from django.shortcuts import HttpResponse, render, redirect

  HttpResponse:内部传入一个字符串参数,返回给浏览器。

  render:除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。将数据填充进模板文件,最后把结果返回给浏览器。

  redirect:接受一个URL参数,表示跳转到指定的URL。

参考链接:https://www.cnblogs.com/hxf175336/p/9332409.html

     https://www.cnblogs.com/hxf175336/p/9449771.html

表单的处理方式:

常见的三种方式:原生form、form组件、ModelForm组件,以Book表的add为例子分别说明一下这三种方式。

 

 

原生Form:

from django.shortcuts import render, HttpResponse, redirect

from .models import *


# Create your views here.
def books(request):
    book_list = Book.objects.all()
    return render(request, "books.html", locals())


# 普通add创建方法
def add_book(request):
    if request.method == "POST":
        title = request.POST.get("title")
        price = request.POST.get("price")
        date = request.POST.get("date")
        publish = request.POST.get("publish")
        author = request.POST.getlist("author")
        # 创建数据库字段
        book_obj = Book.objects.create(title=title, price=price, date=date, publish_id=publish)
        # 创建多对对字段
        book_obj.authors.add(*author)
        return redirect("/books/")

    publish_list = Publish.objects.all()
    author_list = Author.objects.all()

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


def edit_book(request, id):
    if request.method == "POST":
        title = request.POST.get("title")
        price = request.POST.get("price")
        date = request.POST.get("date")
        publish = request.POST.get("publish")
        author_pk_list = request.POST.getlist("author")
        # filter过滤找到指定的值后,直接可以updata更新字段
        Book.objects.filter(pk=id).update(title=title, price=price, date=date, publish=publish)
        # 多对多字段更新
        book_obj = Book.objects.filter(pk=id).first()  # first 找到具体对象 就可以点跨表取值
        book_obj.authors.set(*author_pk_list)  # 进行多对多字段更新
        return redirect("/books/")

    edit_book = Book.objects.filter(id=id).first()  # 利用first可以直接把单个值拿出来,前端可以用点取值
    publish_list = Publish.objects.all()
    author_list = Author.objects.all()

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

template:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<a href="/book_add/"><button>添加书籍</button></a>

<hr>
<table border="1">
    {% for book in book_list %}
        <tr>
        <td>{{ book.title }}</td>
        <td>{{ book.price }}</td>
        <td>{{ book.date|date:"Y-m-d" }}</td>
        <td>{{ book.publish.name }}</td>
        <td>{{ book.publish.all }}</td>
        <td>{% for author in  book.authors.all %}
            {{ author }}
        {% endfor %}

        </td>
        <td><button><a href="/book_edit/{{ book.id }}/">编辑</a></button></td>
        </tr>

    {% endfor %}

</table>



</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>

<h3> 编辑页面</h3>


<form action="/book_edit/{{ edit_book.id }}/" method="post">
    {% csrf_token %}
    <p>书籍名称<input type="text" name="title" value="{{ edit_book.title }}"></p>
    <p>价格<input type="text" name="price" value="{{ edit_book.price }}"></p>
    <p>日期<input type="date" name="date" value="{{ edit_book.date|date:"Y-m-d" }}"></p>
    <p>出版社

        <select name="publish" id="">
            {% for publish in publish_list %}
                <!--值的学习的地方-->
                {% if edit_book.publish == publish %}
                    <option selected value="{{ publish.id }}">{{ publish.name }}</option>
                {% else %}
                    <option value="{{ publish.id }}">{{ publish.name }}</option>
                {% endif %}

            {% endfor %}

        </select>

    <p>作者

        <select name="author" id="" multiple>
            {% for author in author_list %}
                <!--值的学习的地方-->
                {% if author in edit_book.authors.all %}
                    <option selected value="{{ author.id }}">{{ author.name }}</option>
                {% else %}
                    <option value="{{ author.id }}">{{ author.name }}</option>
                {% endif %}

            {% endfor %}
        </select>

    </p>
    <p>
        <button type="submit">提交</button>
    </p>

</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<h3>添加页面</h3>


<form action="/book_add/" method="post">
    {% csrf_token %}
    <p>书籍名称<input type="text" name="title"></p>
    <p>价格<input type="text" name="price"></p>
    <p>日期<input type="date" name="date"></p>
    <p>出版社

        <select name="publish" id="">
        {% for publish in publish_list %}
            <option value="{{ publish.id }}">{{ publish.name }}</option>
        {% endfor %}

        </select>

    <p>作者

    <select name="author" id="" multiple>
        {% for author in author_list %}
            <option value="{{ author.id }}">{{ author.name }}]</option>
        {% endfor %}
    </select>

    </p>
<p><button type="submit">提交</button></p>

</form>


</body>
</html>

效果图:

技术图片

 

 

 

Form组件:

前端页面两中形式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<form action="">
    {% csrf_token %}
    <div>
        {{ form.title.label }}
        {{ form.title }}
    </div>

    <div>
        {{ form.price.label }}
        {{ form.price }}
    </div>

    <div>
        {{ form.date.label }}
        {{ form.date }}
    </div>

    <div>
        {{ form.pubilish.label }}
        {{ form.pubilish }}
    </div>
    <div>
        {{ form.author.label }}
        {{ form.author }}
    </div>

    <input type="submit">
</form>

</body>
</html>

2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<h3>添加页面</h3>

<form action="/book_add/" method="post">
    {% csrf_token %}
    {% for field in form %}
        <div>
            {{ field.label }}
            {{ field}}
        </div>
    {% endfor %}

    <input type="submit">
</form>


</body>
</html>

2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>

<h3> 编辑页面</h3>
<form action="" method="post">
    {% csrf_token %}
    {% for field in form %}

    <div>
        {{ field.label }}
        {{ field }}
    </div>
    {% endfor %}
    <input type="submit">
</form>

</body>
</html>

Form view视图:

# 原生form 创建方法
def add_book(request):
    if request.method == "POST":
        # 我调用了form吧request值传进去让他帮我做校验
        form = BookForm(request.POST)
        # form.cleaned_data里面的数据
        """
        {‘title‘: ‘fdasfdsa24323‘, 
        ‘price‘: Decimal(‘123212‘),
         ‘date‘: datetime.date(2019, 10, 17),
          ‘pubilish‘: <Publish: 香蕉出版社>,
          ‘author‘: <QuerySet [<Author: egen>]>} 
        """

        if form.is_valid():
            # 需要用cleaned_data取值
            title = form.cleaned_data.get("title")
            price = form.cleaned_data.get("price")
            date = form.cleaned_data.get("date")
            # 一对多字段和多对多字段需要在request里面取值
            publish_id = request.POST.get("pubilish")
            author_pk_list = request.POST.getlist("author")
            book_obj = Book.objects.create(title=title, price=price, date=date, publish_id=publish_id)
            book_obj.authors.add(*author_pk_list)
            return redirect("/books/")

    form = BookForm()
    return render(request, "add_book.html", locals())
def edit_book(request, id):
    if request.method == "POST":
        # 我调用了form吧request值传进去让他帮我做校验
        form = BookForm(request.POST)
        # form.cleaned_data里面的数据
        """
        {‘title‘: ‘fdasfdsa24323‘, 
        ‘price‘: Decimal(‘123212‘),
         ‘date‘: datetime.date(2019, 10, 17),
          ‘pubilish‘: <Publish: 香蕉出版社>,
          ‘author‘: <QuerySet [<Author: egen>]>} 
        """

        if form.is_valid():
            # 需要用cleaned_data取值
            title = form.cleaned_data.get("title")
            price = form.cleaned_data.get("price")
            date = form.cleaned_data.get("date")
            # 一对多字段和多对多字段需要在request里面取值
            publish_id = request.POST.get("pubilish")
            author_pk_list = request.POST.getlist("author")

            Book.objects.filter(pk=id).update(title=title, price=price, date=date, publish=publish_id)
            # 多对多字段更新
            book_obj = Book.objects.filter(pk=id).first()  # first 找到具体对象 就可以点跨表取值
            book_obj.authors.set(*author_pk_list)  # 进行多对多字段更新
        return redirect("/books/")

    edit_book = Book.objects.filter(id=id).first()  # 利用first可以直接把单个值拿出来,前端可以用点取值

    form = BookForm()
    #  python2.26版本貌似没有了instance字段,无法在编辑时选中编辑的字段
    # form = BookForm(instance=edit_book)

    return render(request, "edit_book.html", locals())
# ModelForm 创建方法:

技术图片

 

 

 前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<h3>添加页面</h3>

<form action="/book_add/" method="post">
    {% csrf_token %}
    {% for field in form %}
        <div>
            {{ field.label }}
            {{ field }}
        </div>
    {% endfor %}

    <input type="submit">
</form>


</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h3> 编辑页面</h3>
            {% include "form.html" %}
        </div>
    </div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--配置手机端适应-->
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <!--配置css文件 核心CSS样式压缩文件-->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">
    <!--配置jQuery-->
    <script src="/static/bootstrap/jQuery.js"></script>
    <!--配置 核心Boot script JS压缩文件-->
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h3>添加页面</h3>
            {% include "add.html" %}
        </div>

    </div>
</div>


</body>
</html>

 

view视图:

class BookForm(ModelForm):
    class Meta:
        model = Book
        fields = "__all__"
        # 自定义属性的方法
        widgets = {
            "date": wid.DateInput(attrs={"type": "date","class": "form-control"}),  # 还可以自定义属性
            "title": wid.DateInput(attrs={"class": "form-control"}),
            "price": wid.DateInput(attrs={"class": "form-control"}),
            "publish": wid.Select({"class" : "form-control"}),
            "authors": wid.SelectMultiple(attrs={"class" : "form-control"}),
        }

        # labels,自定义在前端显示的名字
        labels = {
            "date": "时间",
            "title": "用户名",
            "price": "价格",
            "publish": "出版社",
            "authors": "作者",

        }

 

# ModelForm 创建方法
def add_book(request):
    if request.method == "POST":
        form = BookForm(request.POST)
        if form.is_valid():
            form.save()  # 这个叼 这个叼
            return redirect("/books/")
    form = BookForm()
    return render(request, "add_book.html", locals())
def edit_book(request, id):
    if request.method == "POST":
        form = BookForm(request.POST)
        if form.is_valid():
            form.save()  # 这个叼 这个叼
            return redirect("/books/")

    edit_book = Book.objects.filter(pk=id).first()
    # ModelForm是有instance这个字段的,主要用于 编辑时可以默认选中当前编辑字段
    form = BookForm(instance=edit_book)
    return render(request, "edit_book.html", locals())

mo

以上是关于原生Form 和 Form组件 Modelform的主要内容,如果未能解决你的问题,请参考以下文章

原生form表单,form,modelform

Django基础十之Form和ModelForm组件

Form和ModelForm组件

Form和ModelForm组件

Form和ModelForm组件1

django form和ModelForm组件