Django 學習3--CreateView

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

其他文件和上面一樣,啓動後效果

 保存後->

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章