django modelform模块

一、modelform的用处

ModelForm可以将Model与Form进行绑定,Form有自动生成表单的作用,但是每一个forms字段需要自己手动填写,而Model就是数据库表包含了所有的数据字段。所以ModelForm有着以下功能:

  • Form所有的功能。
  • 将Model字段自动转换成forms字段。

二、在界面上展示input标签。

1、新建forms.py文件,并键入以下代码:

from django import forms
from .models import Question, Choice


class ChoiceForm(forms.ModelForm):
        choice_text = forms.CharField(
            label="你的答案",       # 自定义在前端显示的名字
            max_length=200,       # 指定输入长度
            help_text='最大长度为200',              # 提示帮助信息
            widget=forms.TextInput(        # 指定输入类型
                attrs={
                    'placeholder': "请说出你的答案",          # 自定义input的属性
                    "class": 'form-control'
                }
            )
        )
        class Meta: 
            model = Choice     # model类
            fields = ['choice_text']   # 字段名,如果是__all__,就是表示列出所有的字段

2、在view.py文件中引用

from .forms import ChoiceForm

 def reply(request, question_id):
    try:
        if request.method == "GET":    
            form = ChoiceForm()
        return render(request, 'bbs/detail.html', {
            'form': forms
        })

3、只需要在前端的页面把{{ form.as_p }} 进行引用即可

效果如下:

 

 

 

三、前后端交互,数据存储到后台。

此时,在界面上input框上键入值后点提交,后台还没能收到数据并存储,还需要以下的操作。

1、键入提交后的指定发送到那个函数上进行存储。

        <form action="{% url 'bbs:reply' question.id %}" method="post">   # 指明提交到那个函数
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="提交">
        </form>

 

2、编辑view.py reply函数。

if request.method == 'POST':
            form = ChoiceForm(request.POST)   # 获取提交数据的对象
            print('form:', form)
            if form.is_valid():   # 校对数据是否合法,比如是否为空之类的额
                reply = form.save(commit=False)    # 提交数据,该数据是写入input的值,但不写入数据库
                print('reply: ', reply, type(reply))
                reply.question = question          # 绑定到一个问题,因为这里的表引用了外键question,因此需要绑定。
                reply.save()   # 写入数据库
            return HttpResponseRedirect(reverse('bbs:detail', args=(question.id,)))

 

四、上传图片操作  

编辑form.py文件,在原来的基础上新增上传文件的配置:

from django import forms
from .models import Question, Choice


class ChoiceForm(forms.ModelForm):
        choice_text = forms.CharField(
            label="你的答案",       
            max_length=200,       
            help_text='最大长度为200',              
            widget=forms.TextInput(       
                attrs={
                    'placeholder': "请说出你的答案",         
                    "class": 'form-control'
                }
            )
        )
        picture = forms.FileField(    # 指定输入信息的配型,上传文件为FileField,文本为CharField类型
        label="添加图片(可选)",
        help_text='可以上传的格式: jpg, png',
        required = False,     # 是否为必填选项,默认为True.
        widget=forms.FileInput(
            attrs={
                "class": 'form-control'
            }
        )
    )
        class Meta: 
            model = Choice     # model类
            fields = ['choice_text', 'picture']  # 字段名,如果是__all__,就是表示列出所有的字段

 

接下来的步骤和第二步骤的2、3步骤一样,{{ form.as_p }}会循环展示input标签,即你form里面设置了展示多少个标签,在界面上就会展示多个input输入框。

 

五、把图片存储到后台。

1、需要在项目的settings.py文件中添加图片的位置。

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

2、在项目的urls.py文件中指明media的url访问路径。

from django.contrib import admin
from django.urls import path
from django.urls import include
from django.conf import settings        # 导入以下两个模块
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('polls/', include("polls.urls")),
    path('bbs/', include("bbs.urls")),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)   # 把media路径添加进urlpattern路径中

  

3、修改上传文件并提交的指定函数:

if request.method == 'POST':
            form = ChoiceForm(request.POST, request.FILES)   # equest.FILES 把文件传给ChoiceForm对象,由ChoiceForm进行处理
            print('form:', form, request.FILES)
            if form.is_valid():
                reply = form.save(commit=False)
                print('reply: ', reply, type(reply))
                reply.question = question
                reply.save()
            return HttpResponseRedirect(reverse('bbs:detail', args=(question.id,)))

 

3、确保form标签含有enctype="multipart/form-data"属性,上传文件必须要带的属性,不然会上传失败。

 

六、让界面提交的函数在界面上展示。

需要在前端的页面引用这个picture字段:

{% if q.picture %}
      <img src="{{  obj.picture.url }}" alt="reply_img">    
{% endif %}

  

 

七、修改前端input的样式。

如果需要修改input标签的要是,可以把input里面的标签都取出来,再通过css进行演示的修改。

{% for q in question.choice_set.all %}      # 循环取出所有的input标签
<div class="media text-muted pt-3">
  <p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">   
    <strong class="d-block text-gray-dark">{{ q.author }}</strong>   # 每个q对象里面包含了input的所有属性
    {{ q.choice_text }}
    {% if c.picture %}
    <img src="{{ q.picture.url }}" alt="reply-image"  class="reply-image">
    {% endif %}
  </p>
</div>
{% endfor %}

  

 

 

  

posted @ 2020-03-18 17:26  不负流年  阅读(350)  评论(0编辑  收藏  举报