Python全栈之路-Django(十五)

1 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'^classes/', views.classes),
    url(r'^add_class/', views.add_class),
    url(r'^edit_class/(d+)/', views.edit_class),

    url(r'^students/', views.students),
    url(r'^add_student/', views.add_student),
    url(r'^edit_student/(d+)/', views.edit_student),

    url(r'^teachers/', views.teachers),
    url(r'^add_teacher/', views.add_teacher),
    url(r'^edit_teacher/(d+)/', views.edit_teacher),
]

app01.views.py

class TeacherForm(Form):
    tname = fields.CharField(min_length=2)
    # xx = fields.CharField(
        # widget=widgets.Select(
        #     choices=models.Classes.objects.values_list('id', 'title'),
        #     attrs={'multiple': 'multiple'}
        # )
        # widget=widgets.SelectMultiple(
        #     choices=models.Classes.objects.values_list('id', 'title'),
        # )
    # )
    # xx = fields.ChoiceField(
    #     choices=models.Classes.objects.values_list('id','title'),
    #     widget=widgets.SelectMultiple
    # )
    xx = fields.MultipleChoiceField(
        choices=models.Classes.objects.values_list('id','title'),
        widget=widgets.SelectMultiple
    )
    def __init__(self,*args,**kwargs):  # 解决数据无法动态显示的Bug,推荐使用
        super(TeacherForm,self).__init__(*args,**kwargs)
        self.fields['xx'].widget.choices=models.Classes.objects.values_list('id','title')

def teachers(request):
    tea_list = models.Teacher.objects.all()
    return render(request, 'teachers.html', {'tea_list': tea_list})



def add_teacher(request):
    if request.method == 'GET':
        obj = TeacherForm()

        return render(request, 'add_teacher.html', {'obj': obj})
    else:
        obj = TeacherForm(request.POST)
        if obj.is_valid():
            xx = obj.cleaned_data.pop('xx')
            row = models.Teacher.objects.create(**obj.cleaned_data)
            row.c2t.add(*xx)
            return redirect('/teachers/')
        else:
            print(obj.errors)
            return render(request, 'add_teacher.html', {'obj': obj})

def edit_teacher(request, nid):
    if request.method == 'GET':
        row = models.Teacher.objects.filter(id=nid).first()
        cls_id = row.c2t.values_list('id')
        id_list = list(zip(*cls_id))[0] if list(zip(*cls_id)) else []
        obj = TeacherForm(initial={'tname': row.tname,'xx': id_list})
        return render(request, 'edit_teacher.html',{'obj':obj,'nid':nid})
    else:
        obj = TeacherForm(request.POST)
        if obj.is_valid():
            xx = obj.cleaned_data.pop('xx')
            models.Teacher.objects.filter(id=nid).update(**obj.cleaned_data)
            row = models.Teacher.objects.filter(id=nid).first()
            row.c2t.set(xx)
            return redirect('/teachers/')
        else:
            return render(request, 'edit_teacher.html',{'obj':obj,'nid':nid})

templates.teachers.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>老师列表</h1>
    <p><a href="/add_teacher/">添加</a></p>
    <table>
        <thead>
            <tr>
                <td>ID</td>
                <td>老师姓名</td>
                <td>任教班级</td>
                <td>操作</td>
            </tr>
        </thead>
        <tbody>
            {% for t in tea_list %}
                <tr>
                    <td>{{ t.id }}</td>
                    <td>{{ t.tname }}</td>
                    <td>
                    {% for item in t.c2t.all %}
                        {{ item.title }}
                    {% endfor %}
                    </td>
                    <td><a href="/edit_teacher/{{ t.id }}/">编辑</a></td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    <ul>

    </ul>
</body>
</html>

templates.add_teacher.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>添加老师</h1>
    <form action="/add_teacher/" method="post">
        {% csrf_token %}
        <p>
            姓名:{{ obj.tname }}
        </p>
        <p>
            班级:{{ obj.xx }}
        </p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

templates.edit_teacher.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>编辑老师</h1>
    <form action="/edit_teacher/{{ nid }}/" method="post" novalidate>
        {% csrf_token %}
        <p>{{ obj.tname }}</p>
        <p>{{ obj.xx }}</p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

2 Form组件

2.1 单选框和多选框

多选框:

 cls_id = fields.MultipleChoiceField(
    choices=models.Classes.objects.values_list('id','title'),
    widget=widgets.SelectMultiple
)

单选框:

cls_id_id = fields.IntegerField(
    widget=widgets.Select(
        choices=models.Classes.objects.all().values_list('id', 'title'),
        attrs={'class': 'form-control'}
    )
)
cls_id_id = fields.IntegerField(
    widget=widgets.Select(
        choices=models.Classes.objects.all().values_list('id', 'title'),
        attrs={'class': 'form-control'}
    )
)

2.2 Form 其他常用组件

class TestForm(Form):
    t1 = fields.CharField(
        widget=widgets.Textarea(attrs={})
    )

    t2 = fields.CharField(
        widget=widgets.CheckboxInput
    )
    t3 = fields.MultipleChoiceField(
        choices=[(1, 'basketball'),(2, 'football'),(3, 'voliball')],
        widget=widgets.CheckboxSelectMultiple
    )
    t4 = fields.ChoiceField(
        choices=[(1,'basketball'),(2,'football'),(3,'voliball')],
        widget=widgets.RadioSelect
    )

    t5 = fields.CharField(
        widget=widgets.PasswordInput(attrs={})
    )
    t6 = fields.FileField(
        widget=widgets.FileInput
    )

def test(request):
    obj = TestForm({'t3': [2, 3], })
    return render(request,'test.html',{'obj':obj})

2.3 Form组件扩展

- is_valid
    - 字段 = 默认正则表达式
            - 额外的正则
            from django.forms import Form
            from django.forms import widgets
            from django.forms import fields
            from django.core.validators import RegexValidator
                
            class MyForm(Form):
                user = fields.CharField(
                    validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
                )
    - clean_字段,必须返回值
    - clean()  
        有返回值:cleaned_data = 返回值
        无返回值:cleaned_data = 原来的值

2.4 Form组件文件上传

import os
def f1(request):
    if request.method == 'GET':
        return render(request, 'f1.html')
    else:
        file_obj = request.FILES.get('fafafa')
        print(type(file_obj))
        print(file_obj.name)
        print(file_obj.size)
        f = open(os.path.join('static',file_obj.name),'wb')
        for chunk in file_obj.chunks():
            f.write(chunk)
        f.close()
        return render(request, 'f1.html')

class F2Form(Form):
    user = fields.CharField()
    fafafa = fields.FileField()
def f2(request):
    if request.method == 'GET':
        obj = F2Form()
        return render(request, 'f2.html',{'obj': obj})
    else:
        file_obj = request.FILES.get('fafafa')
        obj = F2Form(data=request.POST,files=request.FILES)
        print(type(file_obj))
        print(file_obj.name)
        print(file_obj.size)
        f = open(os.path.join('static', file_obj.name), 'wb')
        if obj.is_valid():
            print(obj.cleaned_data)
            print(obj.cleaned_data.get('fafafa').name)
            print(obj.cleaned_data.get('fafafa').size)
            f = open(os.path.join('static', obj.cleaned_data.get('fafafa').name), 'wb')
            for chunk in obj.cleaned_data.get('fafafa'):
                f.write(chunk)
            f.close()
            return render(request, 'f2.html', {'obj': obj})
        else:
            print(obj.errors)
            return render(request, 'f2.html', {'obj': obj})
原文地址:https://www.cnblogs.com/wanyuetian/p/7141521.html