码迷,mamicode.com
首页 > 其他好文 > 详细

ModelForm的使用

时间:2018-08-26 22:07:15      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:for循环   submit   序号   isp   src   日志打印   ima   event   als   

一,form组件-图书管理系统

图书管理系统:点我

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^book_list, views.book_list),
    url(r^add_book, views.add_book),
    url(r^edit_book/(\d+), views.edit_book)
]

models.py

技术分享图片
from django.db import models

# Create your models here.


class Publish(models.Model):
    name = models.CharField(max_length=32, null=False)
    addr = models.CharField(max_length=64)

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="姓名")
    gender = models.SmallIntegerField(
        choices=((0, ""), (1, ""), (2, "不明"))
    )
    age = models.IntegerField()

    def __str__(self):
        return self.name


class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name="书名")
    price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="价格")
    publish_date = models.DateField(verbose_name="出版日期")
    publisher = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
    authors = models.ManyToManyField(to="Author")

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

my_forms.py

from django import forms
from app01 import models


class BookForm(forms.Form):
    title = forms.CharField(max_length=32, label="书名")
    price = forms.DecimalField(max_digits=5, decimal_places=2)
    publish_date = forms.DateField(
        widget=forms.widgets.TextInput(
            attrs={"type": "date"}
        )
    )
    # 这样写可以实现添加书籍,不能实现编辑书籍,因为编辑书籍需要显示要编辑的这本数的原来的出版社和作者
    # 即需要默认值,无法操作
    # publisher = forms.ChoiceField(
    #     choices=models.Publish.objects.all().values_list("id", "name"),
    #     widget=forms.widgets.Select()
    # )
    # authors = forms.ChoiceField(
    #     choices=models.Author.objects.all().values_list("id", "name"),
    #     widget=forms.widgets.SelectMultiple()
    # )

    # 解决上述不能实现编辑书籍的问题
    publisher = forms.ModelChoiceField(
        queryset=models.Publish.objects.all()
    )
    authors = forms.ModelMultipleChoiceField(
        queryset=models.Author.objects.all()
    )

views.py

from django.shortcuts import render, redirect
from app01 import models
from app01.myforms import BookForm
from django.forms.models import model_to_dict
# Create your views here.

# 日志操作
import logging logger = logging.getLogger(__name__) # 生成一个以当前文件名为名字的日志实例对象 collect_logger = logging.getLogger("collect") # 生成一个名字是collect的日志实例对象 def book_list(request): book_list_obj = models.Book.objects.all() return render(request, "book_list.html", {"book_list_obj": book_list_obj}) # 使用一般的form组件 def add_book(request): form_obj = BookForm() # publisher = models.Publish.objects.all() # 使用form组件不需要传了 # authors = models.Author.objects.all() # # 使用form组件不需要传了 if request.method == "POST": form_obj = BookForm(request.POST) if form_obj.is_valid(): authors = form_obj.cleaned_data.pop("authors") book_obj = models.Book.objects.create(**form_obj.cleaned_data) # book_obj.authors.add(*authors) # 二者都可以 book_obj.authors.set(authors) # 既可以是对象列表,又可以是id列表 return redirect("/book_list/") return render(request, "add_book.html", {"form_obj": form_obj}) def edit_book(request, pk): book_obj = models.Book.objects.filter(id=pk).first() dic_obj = model_to_dict(book_obj) # 把一个对象转换为字典的格式 print(dic_obj) form_obj = BookForm(initial=dic_obj) # 注意这里的initial,传入的是一个字典的形式,指定默认值(编辑书籍需要有默认值) if request.method == "POST": form_obj = BookForm(request.POST) if form_obj.is_valid(): # form组件写的 只能一个一个写,不过变成从form_obj.cleaned_data中取值 title = form_obj.cleaned_data.get("title") price = form_obj.cleaned_data.get("price") publish_date = form_obj.cleaned_data.get("publish_date") publisher = form_obj.cleaned_data.get("publisher") authors = form_obj.cleaned_data.get("authors") book_obj.title = title book_obj.price = price book_obj.publish_date = publish_date book_obj.publisher_id = publisher book_obj.save() book_obj.authors.set(authors) # 可以是对象列表,又可以是id列表 return redirect("/book_list/") return render(request, "edit_book.html", {"form_obj": form_obj})

templates

技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1">
    <a href="/add_book/">添加书籍</a>
    <thead>
    <tr>
        <th>序号</th>
        <th>id</th>
        <th>书名</th>
        <th>作者</th>
        <th>出版社</th>
        <th>出版日期</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for book_obj in book_list_obj %}
        <tr>
        <td>{{ forloop.counter }}</td>
        <td>{{ book_obj.id }}</td>
        <td>{{ book_obj.title }}</td>
        <td>
            {% for author in book_obj.authors.all %}
                {{ author.name }}
            {% endfor %}
        </td>
        <td>{{ book_obj.publisher.name }}</td>
        <td>{{ book_obj.publish_date|date:"Y-m-d" }}</td>
        <td>
            <a href="/edit_book/{{ book_obj.id }}">编辑</a>
            <a href="/del_book/{{ book_obj.id }}">删除</a>
        </td>
        </tr>
    {% endfor %}

    </tbody>
</table>
</body>
</html>
book_list.html
技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    <!-- 原本这样写
    <label for="{{ form_obj.publish_date.id_for_label }}">{{ form_obj.publish_date.label}}</label>
    {{ form_obj.publish_date }}
    {{ form_obj.publish_date.errors.0 }}
    <hr>
    {{ form_obj.publish_date.label }}
    {{ form_obj.publish_date }}
    <hr>
    -->

    <!-- for循环写法和上面一样 -->
    {% for filed in form_obj %}
        <p>
        {{ filed.label}}
        {{ filed }}
        </p>
        {{ filed.errors }}
    {% endfor %}
    <p>
        <input type="submit">
    </p>
</form>
</body>
</html>
add_book.html
技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}

    {% for filed in form_obj %}
        <p>
        {{ filed.label}}
        {{ filed }}
        </p>
        {{ filed.errors }}
    {% endfor %}
    <p>
        <input type="submit">
    </p>
</form>
</body>
</html>
edit_book.html

二,ModelForm-图书管理系统

my_forms.py

from django import forms
from app01 import models

class BookModelForm(forms.ModelForm):

    class Meta:
        # 告诉Django这个form类和那个model类对应
        model = models.Book
        # 告诉Django这个form类里面有哪些字段
        fields = "__all__"  # 所有字段
        # fields = ["title", "price"]
        # exclude = ["authors"]  # 不要authors
        widgets = {
            "publish_date": forms.widgets.DateInput(
                attrs={"type": "date", "class": "form-control"}  # 也可以加bootstrap样式
            )
        }
        labels = {
            "title": "书名",
            "price": "价格",
            "publish_date": "出版日期"
        }
        error_messages = {
            "title": {
                "required": "书名不能为空"
            }
        }

views.py

from django.shortcuts import render, redirect
from app01 import models
# Create your views here.
from app01.myforms import BookModelForm
import logging

logger = logging.getLogger(__name__)  # 生成一个以当前文件名为名字的日志实例对象
collect_logger = logging.getLogger("collect")  # 生成一个名字是collect的日志实例对象


def book_list(request):
    book_list_obj = models.Book.objects.all()
    return render(request, "book_list.html", {"book_list_obj": book_list_obj})

# 使用modelform   解决上面编辑时代码重复写
def add_book(request):
    form_obj = BookModelForm()
    # publisher = models.Publish.objects.all()  # 使用form组件不需要传了
    # authors = models.Author.objects.all()  # # 使用form组件不需要传了
    if request.method == "POST":
        form_obj = BookModelForm(request.POST)
        if form_obj.is_valid():
            # 使用BookModelForm,下面的都不需要,只需save()
            # authors = form_obj.cleaned_data.pop("authors")
            # book_obj = models.Book.objects.create(**form_obj.cleaned_data)
            # # book_obj.authors.add(*authors)  # 二者都可以
            # book_obj.authors.set(authors)  # 既可以是对象列表,又可以是id列表
            form_obj.save()
            return redirect("/book_list/")
    return render(request, "add_book.html", {"form_obj": form_obj})


def edit_book(request, pk):
    # 日志打印练习
    logger.debug(又要编辑id值是{}的书籍了....format(pk))
    logger.info(又要编辑id值是{}的书籍了....format(pk))
    collect_logger.warning("id是{}的书籍又被人编辑了...".format(pk))

    book_obj = models.Book.objects.filter(id=pk).first()
    form_obj = BookModelForm(instance=book_obj)  # 不需要转化为字典了,直接传对象
    if request.method == "POST":
        form_obj = BookModelForm(request.POST, instance=book_obj)
        if form_obj.is_valid():
            form_obj.save()
            return redirect("/book_list/")
    return render(request, "edit_book.html", {"form_obj": form_obj})

三,关于ModelForm

form与model的终极结合。

class Meta:下常用参数:

model = models.Student  # 对应的Model中的类
fields = "__all__"  # 字段,如果是__all__,就是表示列出所有的字段
exclude = None  # 排除的字段
labels = None  # 提示信息
help_texts = None  # 帮助提示信息
widgets = None  # 自定义插件
error_messages = None  # 自定义错误信息

 

ModelForm的使用

标签:for循环   submit   序号   isp   src   日志打印   ima   event   als   

原文地址:https://www.cnblogs.com/glh-ty/p/9538930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!