标签: ModelForm

  • Django – 前端提交数据, 后端接收并入库简例 (ModelForm)

    models.py

     

    class Boss(models.Model):
        name = models.CharField(verbose_name="姓名", max_length=64)
        age = models.IntegerField(verbose_name="年龄")
        img = models.CharField(verbose_name="头像", max_length=256)

     

    这种写法需要在view_name.py文件中去处处理 待保存文件的路径问题, 并调用create方法.

    media_file_path = os.path.join("media", image_object.name)
    print(media_file_path)
    f = open(media_file_path, mode="wb")
    for chunk in image_object.chunks():
        f.write(chunk)
        f.close()
    
    models.Boss.objects.create(
        name = form.cleaned_data['name'],
        age = form.cleaned_data['age'],
        img = media_file_path,

     

     

    class City(models.Model):
        name = models.CharField(verbose_name="名称", max_length=64)
        count = models.IntegerField(verbose_name="人口")
    
        # 此处写成"FileField", 而不是"IntegerField", 这样FileField会多出upload_to='目录名'属性, 在入库时可快速将图片保存到该目录
        logo = models.FileField(verbose_name="logo", max_length=256, upload_to='city/')

     

    view_name.py

    class UpModelForm(BootStrapModelForm):
        class Meta:
    
            model = models.City
            fields = "__all__"
    
    def upload_model_form(request):
        title = "ModelForm上传"
        if request.method == "GET":
            form = UpModelForm()
            return render(request, 'upload_form.html', {'form': form, "title": title})
    
    
        form = UpModelForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponse('成功')

     

    可以看到这种写法非常简捷,  保存路径已在创建model时设置, 而保存数据只需form.save()即可.

    结果验证

    • 保存路径: logo = models.FileField(verbose_name=”logo”, max_length=256, upload_to=’city/’)
    • 如何保存: form.save()

     

     

    前置条件

    配置media目录. (实际使用中, 由于目录位置等差异, 根据实际情调整.)

    setting.py

    MEDIA_ROOT = os.path.join(BASE_DIR, "media")
    MEDIA_URL = "/media/"

     

    urls.py 路由

     

    from django.views.static import serve
    from django.conf import settings
    re_path(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}, name='media'),

     

  • Django – Form和ModelForm组件

    表单的很多字段信息, 和models.py文件里的模型是一致的,为了避免重复代码,以及提高效率, 可以使用ModelForm,将模型和表单进行绑定。

    Form

    views.py

    //创建业务类MyForm, 继承django中Form类
    class MyForm(Form):  
        // Form类会在html中渲染出原始表单
        user = forms.CharField(widget=forms.Input)
        pwd = form.CharFiled(widget=forms.Input)
        email = form.CharFiled(widget=forms.Input)
        account = form.CharFiled(widget=forms.Input)
        create_time = form.CharFiled(widget=forms.Input)
        depart = form.CharFiled(widget=forms.Input)
        gender = form.CharFiled(widget=forms.Input)
    
    
    def user_add(request):
        if request.method == "GET":
            form = MyForm()
            return render(request, 'user_add.html',{"form":form})

     

    user_add.html (Form)

    <form method="post">
        {% for field in form%}
        	{{ field }}
        {% endfor %}
        <!-- <input type="text"  placeholder="姓名" name="user" /> -->
    </form>

    或者

    <form method="post">
        {{ form.user }}
        {{ form.pwd }}
        {{ form.email }}
        <!-- <input type="text"  placeholder="姓名" name="user" /> -->
    </form>

     

     

    ModelForm

     

    models.py 

    class UserInfo(models.Model):
        """ 员工表 """
        name = models.CharField(verbose_name="姓名", max_length=16)
        password = models.CharField(verbose_name="密码", max_length=64)
        age = models.IntegerField(verbose_name="年龄")
        account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
        create_time = models.DateTimeField(verbose_name="入职时间")
        depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
        gender_choices = (
            (1, "男"),
            (2, "女"),
        )
        gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

     

     

    views.py 快速建立表单

    class UserModelForm(forms.ModelForm):
        name = forms.CharField(min_length=2, label="用户名")
        password = forms.CharField(label="密码")
        class Meta:
            model = UserInfo
            fields = ["name","password","age","xx"]
    
    
    def user_add(request):
        if request.method == "GET":
            form = MyForm()
            return render(request, 'user_add.html',{"form":form})

    views.py 给表单添加样式

     

    class UserModelForm(forms.ModelForm):
        name = forms.CharField(min_length=2, label="用户名")
        password = forms.CharField(label="密码")
        # create_time = forms.DateTimeField()
        class Meta:
            model = models.UserInfo
            fields = ['name', 'password', 'age', 'account', 'create_time', 'gender', 'depart']
            
            # 方法1: 为前端元素添加类属性, 使其获得样式. 
    
            # widgets = {
            #     "name":forms.TextInput(attrs={"class":"form-control"})
            # }
    
            # 方法2: 为前端元素添加类属性, 使其获得样式. 
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)  #super() 函数是用于调用父类(超类)的一个方法。
            for name, field in self.fields.items():
                field.widget.attrs = {"class":"form-control", "placeholder":field.label}
    

     

     

    user_add.html (ModelForm)

    <form method="post" novalidate>
        {% csrf_token %}
    
        {% for field in form %}
            <div class="form-group">
                <label>{{ field.label }}</label>
                {{ field }}
                <span style="color: red">{{ field.errors.0 }}</span>
            </div>
        {% endfor %}
    
        <button type="submit" class="btn btn-primary">提交</button>
    
    </form>