1. 程式人生 > >djagon實戰form數據庫等操作

djagon實戰form數據庫等操作

實例班級

實例項目

項目需求分析

通過form表單的方式,來實現以下幾個功能
1、html標簽的自動生成
2、上次輸入數據的保留
3、輸入數據的驗證

代碼實施

數據庫代碼

from django.db import models

class Classes(models.Model):
    title = models.CharField(max_length=32)

class Student(models.Model):
    sname = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    age = models.IntegerField()
    cls = models.ForeignKey(‘Classes‘,on_delete=models.CASCADE)

class Teacher(models.Model):
    tname = models.CharField(max_length=32)
    c2t = models.ManyToManyField(‘Classes‘)

數據庫報錯‘on_delete‘

Djiango的時候發現執行mange.py makemigrations 和 migrate是會報錯,少位置參數on_delete,查了一下是因為指定外鍵的方式不對,改一下就OK了。
一對多設計 多方持有一方的外鍵
所以解決方法是:

cls = models.ForeignKey(‘Classes‘)
添加字段變成
cls = models.ForeignKey(‘Classes‘,on_delete=models.CASCADE)

班級管理

由於不小心把django升級到了2.0版本,在做路由的時候發現出現了問題,下面有記錄。2.0是咱們為python3.x出的,先用用看

班級管理功能:
1、班級的列表
2、班級的增加
3、班級的編輯

班級的路由url

from django.contrib import admin
from django.urls import path,re_path
from clsmanagent import views
from django.conf.urls import url

urlpatterns = [
    path(‘class_list/‘, views.class_list),
    path(‘add_class/‘, views.add_class),
    path(‘edit_class/<int:nid>/‘, views.edit_class),

班級管理列表

視圖文件py

from django.shortcuts import render,redirect,HttpResponse
from django.forms import Form, fields,widgets
from clsmanagent import models

# 班級form驗證
class ClassForm(Form):
    title = fields.RegexField(‘全棧\d+‘,label=‘班級名稱‘)

# 班級信息
def class_list(request):
    # if request.method == "GET":
    obj = models.Classes.objects.all()
    return render(request, ‘classlist.html‘, {‘obj‘: obj})

班級的列表的html文件

<h2>班級列表</h2>
<hr>
<span><a href="/add_class/">添加班級</a></span>
{#<form action="/class_list/" method="post">#}
{#    {% csrf_token %}#}
    <ul>
        {% for cls_list in obj %}
            <li>{{ cls_list.title }}<a href="/edit_class/{{ cls_list.id }}/">編輯</a></li>
        {% endfor %}
    </ul>
{#</form>#}

班級增加功能

增加功能視圖文件

#添加班級
def add_class(request):
    if request.method == "GET":
        obj = ClassForm()
        return render(request,‘addclass.html‘,{‘obj‘:obj})
    else:
        obj = ClassForm(request.POST)
        if obj.is_valid():
            models.Classes.objects.create(**obj.cleaned_data)
            return redirect(‘/class_list/‘)
        return render(request, ‘addclass.html‘, {‘obj‘: obj})

增加班級的html代碼

<form action="/add_class/" method="post">
    {% csrf_token %}
    <p>
{#        {{ obj.as_p }}#}
        {{ obj.title }} {{ obj.errors.title.0 }}
    </p>
    <p>
        <input type="submit" value="提交">
    </p>
</form>

編輯班級

編輯班級視圖文件

def edit_class(request,nid):
    if request.method == "GET":
        cls_info = models.Classes.objects.filter(id=nid).first()
        print(cls_info)
        obj = ClassForm(initial={‘title‘:cls_info.title})
        return render(request,‘editclass.html‘,{‘obj‘:obj,‘nid‘:nid})
    else:
        obj = ClassForm(request.POST)
        if obj.is_valid():
            models.Classes.objects.filter(id=nid).update(**obj.cleaned_data)
            return redirect(‘/class_list/‘)
        return render(request,‘editclass.html‘,{‘obj‘:obj,‘nid‘:nid})

編輯班級的html代碼

<body>
    <h2>編輯班級</h2>
    <hr>
    <form action="/edit_class/{{ nid }}/" method="post">
        {% csrf_token %}
        <p>
        {{ obj.title }}{{ obj.errors.title.0 }}
        </p>
        <input type="submit" value="提交">
    </form>

學生表功能

功能和班級功能一樣,這裏就把視圖函數全部放到一起

#學生列表
def student_list(request):
    stu_list = models.Student.objects.all()
    return render(request,‘studentlist.html‘,{‘stu_list‘:stu_list})

#添加學生
##創建學生的Form條件驗證
class StuForm(Form):
    sname = fields.CharField(min_length=2,max_length=6,label=‘學生姓名‘)
    email = fields.EmailField()
    age = fields.IntegerField()
    cls_id = fields.IntegerField(
        widget=widgets.Select(choices=models.Classes.objects.values_list(‘id‘,‘title‘))#把班級變成下拉框,這裏django會自動給我們記錄select的value,不需要我們自己來操心
    )
def add_stu(request):
    if request.method == "GET":
        obj = StuForm()
        return render(request,‘addstudent.html‘,{‘obj‘:obj})
    else:
        obj = StuForm(request.POST)
        if obj.is_valid():
            models.Student.objects.create(**obj.cleaned_data)
            return redirect(‘/student_list/‘)
        return render(request,‘addstudent.html‘,{‘obj‘:obj})

#編輯學生
def edit_stu(request,nid):
    if request.method == "GET":
        row = models.Student.objects.filter(id=nid).values(‘sname‘,‘email‘,‘age‘,‘cls_id‘).first()#讓他變成字典的類型可以傳參到下面的form裏面,因為我們知道表達裏面的data和initial後面都是一個字典類型
        obj = StuForm(row)
        return render(request,‘editstudent.html‘,{‘obj‘:obj,‘nid‘:nid})
    else:
        obj = StuForm(request.POST)
        if obj.is_valid():
            models.Student.objects.filter(id=nid).update(**obj.cleaned_data)#參數我一個字典
            return redirect(‘/student_list/‘)
        return render(request,‘editstudent.html‘,{‘obj‘:obj,‘nid‘:nid})

學生列表html代碼

    <h2>學生列表</h2>
    <hr>
    <a href="/add_stu/">添加學生</a>
    <ul>
        {% for stu in stu_list %}
            <li>{{ stu.sname }}-{{ stu.age }}-{{ stu.email }}-{{ stu.cls_id }}<a href="/edit_stu/{{ stu.id }}/">編輯</a></li>
        {% endfor %}

    </ul>

增加學生html代碼

<form action="/add_stu/" method="post" novalidate>
    {% csrf_token %}
    <h2>添加學生</h2>
    <hr>
    <p>{{ obj.sname }}{{ obj.errors.sname.0 }}</p>
    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
    <p>{{ obj.age }}{{ obj.errors.age.0 }}</p>
    <p>{{ obj.cls_id }}{{ obj.errors.cls_id.0 }}</p>
    <input type="submit" value="提交">
</form>

編輯學生html代碼

<h2>編輯學生信息</h2>
<hr>
<form action="/edit_stu/{{ nid }}" method="post">
    {% csrf_token %}
    <p>{{ obj.sname }}</p>
    <p>{{ obj.email }}</p>
    <p>{{ obj.age }}</p>
    <p>{{ obj.cls_id }}</p>
    <input type="submit" value="提交">
</form>

urls故障

https://docs.djangoproject.com/en/2.0/intro/tutorial02/

django2.0版本主要更新了urls,url變成了path,在使用r‘^edit_class/(\d+)/‘, views.edit_class), 路由的時候,發現報錯404不能找到路徑。經過查看文檔發現2.0v版本以後url變成了path,而path的規則變成了如下:

    <ul>
        {% for cls_list in obj %}
            <li>{{ cls_list.title }}<a href="/edit_class/{{ cls_list.id }}/">編輯</a></li>
        {% endfor %}
    </ul>
from django.urls import path
from . import views
urlpatterns = [
     path(‘edit_class/<int:nid>/‘, views.edit_class),
]

這裏把傳入的參數會變成指定的,不需要(\d+/)了,
轉換格式類型

說明

Str
匹配除分隔符(/)外的非空字符,默認類型<year>等價於<str:year>

Int

匹配0和正整數

Slug

匹配字母、數字、橫杠、下劃線組成的字符串,str的子集

Uuid

匹配格式化的UUID,如075194d3-6885-417e-a8a8-6c931e272f00

path

匹配任何非空字符串,包括路徑分隔符,是全集

djagon實戰form數據庫等操作