Damon_Slh
有志之人

1. 表单

表单有两种:Form和ModelForm

Form是普通的表单,需要我们自己定义一些字段,跟model无关,跟前端有关

ModelForm是跟model有关联的,跟前端也有关,利用后端对model的定义,会对前端的数据进行校验

2.示例

在first_project/personal_info路径下,新建forms.py文件(这是约定俗成的)

 a.Form实现

# 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
from django.views import View
from django.views.generic import ListView

from personal_info.forms import PersionCreateForm
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(View):

    # http请求的get方法会调用的函数
    def get(self, request, *args, **kwargs):
        return render(request, 'personal_info/person_create.html')

    def post(self, request, *args, **kwargs):
        data = request.POST
        form = PersionCreateForm(data=data)
        print(form.is_valid())
        if form.is_valid():
            # 保存数据
            person = Person(
                # cleaned_data是form中有效的数据存储地
                name=form.cleaned_data['name'],
                age=form.cleaned_data['age'],
                gender=form.cleaned_data['gender'],
                address=form.cleaned_data['address'],
                id_card=form.cleaned_data['id_card'],
                temperature=form.cleaned_data['temperature'],
            )
            person.save()
        else:
            raise Exception

        # 跳转,因为前后端不分离的页面,在提交后是一定会跳转的
        return HttpResponseRedirect(reverse('personal_info:person_list'))
first_project/personal_info/views.py
# first_peoject/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"),
]
first_peoject/personal_info/urls.py
# 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/models.py
# first_project/personal_info/forms.py
from django import forms


class PersionCreateForm(forms.Form):
    # 这些跟models中的定义类似
    name = forms.CharField()
    age = forms.IntegerField()
    gender = forms.BooleanField()
    id_card = forms.CharField(max_length=18)
    address = forms.CharField(max_length=256)
    temperature = forms.FloatField()
first_project/personal_info/forms.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登记人员信息</title>
</head>
<body>
<!-- personal_info:person_create 必须要有person_create这个url 效果是请求该url会跳转到这-->
<form action="{% url 'personal_info:person_create' %}" method="post">
    {% csrf_token %}
    <!-- name中的值是后端form定义的字段名字 -->
    <p><label>姓名:<input type="text", name="name"></label></p>
    <p><label>年龄:<input type="number", name="age"></label></p>
    <p><label>姓别:<select name="gender">
        <option value="1"></option>
        <option value="0"></option>
    </select></label></p>
    <p><label>地址:<input type="text", name="address"></label></p>
    <p><label>身份证:<input type="text", name="id_card"></label></p>
    <!-- step是上线点击 -->
    <p><label>体温:<input type="number", name="temperature" step="0.1"></label></p>

    <p><button type="submit">保存</button></p>
</form>

</body>
</html>
first_project/personal_info/templates/personal_info/person_create.html
{% load mytags %} <!-- 导入自定义tag -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>疫情人员登记表</title>
</head>
<body>
    <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>{{ item.name }}</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 -->
    <p><a href="{% url 'personal_info:person_create' %}">登记</a></p>
</body>
</html>
first_project/personal_info/templates/personal_info/person_list.html

启动后的效果

点击登记->  登记完后会跳转到第一个页面,并显示添加的数据,但我这

里获取性别有问题,没找到原因

 

b.ModelForm

 ⚠️使用ModelForm,view要继承CreateView

# 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

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')
first_project/personal_info/views.py
# 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'}) # 可以开发模式打开网页,找到name那行,看到新加了id的字段
        }
        labels = {
            'name':'名字' # 可以看到页面中的原本英文'name'变成了'名字'
        }
first_project/personal_info/forms.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登记人员信息</title>
</head>
<body>
<form action="{% url 'personal_info:person_create' %}" method="post">
    {% csrf_token %}
    {{ form.as_p }} <!-- as_p会按列展示 -->
    <p><button type="submit">保存</button></p>
</form>
</body>
</html>
first_project/personal_info/templates/personal_info/person_create.html

其他文件和上面一样,启动后效果

 保存后->

 

posted on 2021-09-11 21:42  Damon_Slh  阅读(279)  评论(0编辑  收藏  举报