• Django:如何给文章列表添加图片


    思路:

      使用ajax方式将图片和文本一起通过formData提交到后台,Django后台通过request.POST和request.FILES方式接收数据

    1、前端代码

    {% extends 'base.html' %}
    {% load staticfiles %}
    {% block title %}POST ARTICLE{% endblock %}
    {% block content %} 
    <div style="margin-left:10px">
        <form class ="form-hoizontal"  method ="post">{% csrf_token %}
            <div class="form-group" style="margin-top: 10px;">
                <label for="avatar">标题图</label>
                <input type="file" class="form-control-file" name="avatar" id="avatar">
            </div>
    
        <div class ="row" style="margin-top: 10px;">
            <div class="col-md-2 text-right "><span>标题:</span></div>
            <div class="col-md-10 text-left ">{{article_post_form.title}}</div>
        </div>
    
        <div class ="row" style=" margin-top: 10px;">
            <div class="col-md-2 text-right"><span>栏目:</span></div>
            <div class="col-md-10 text-left">
                <select id="which_column">
                    {% for column in article_columns %}
                    <option value=" {{column.id }}">{{column.column}}</option>
                    {% endfor %}
                </select>
            </div>
        </div>
    
        <div class="row" style="margin-top: 10px">
            <div class="col-md-2 text-right"><span>标签:</span></div>
            <div class="col-md-10 text-left">
                {% for tag in article_tags %}
                <input type="checkbox" value="{{ tag.tag }}">{{ tag.tag }}</input>
                {% endfor %}
            </div>
        </div>
    
        <div class ="row" style="margin-top:10px;">
            <div class=" col-md-2 text-right"><span >内容:</span></div>
            <div id="editormd" class=" col-md-10 text-left ">
                <textarea style="display: none;" id="id_body"></textarea>
            </div>
        </div>
        <div class ="row">
            <input type="button" class="btn btn-primary btn-lg" value="发布" onclick="publish_article()" >
        </div>
    </form>
    </div>
    
        <script type="text/javascript" src='{% static "js/jquery.js"%}'></script>
        <script type="text/javascript" src="{% static 'js/layer.js'%}"></script>
        <script type="text/javascript" src="{% static 'editor/editormd.min.js' %}"></script>
        <script type="text/javascript" src="{% static "js/ajaxfileupload.js" %}"></script>
        <script type="text/javascript">
            $(function () {
                var editor = editormd("editormd",{
                    "100%",
                    height:640,
                    syncScrolling:"single",
                    path:"{% static 'editor/lib/' %}"
                });
            });
        </script>
    
        <link rel="stylesheet" href="{% static 'editor/css/style.css' %}">
        <link rel="stylesheet" href="{% static 'editor/css/editormd.css' %}">
    
         <!-- 执行上传文件操作的函数 -->
        <script type="text/javascript">
              function publish_article(){
                  var formData = new FormData();
                  var fileobj=$('#avatar')[0].files[0]; //注意这里的取值方式,获取文件对象
                  formData.append('avatarrrrr', fileobj);
                  {#此处的id=id_title是表单生成的,代码并没有编写此属性#}
                  formData.append('title', $("#id_title").val());
                  formData.append('column_id', $("#which_column").val());
                  formData.append('body', $("#id_body").val());
                  $.ajax({
                      url:"{% url 'article:article_post' %}",
                      {#一定不要写成小写了,坑了好久#}
                      type: 'POST',
                      {#mimeType: "multipart/form-data",#}
                      {#告诉jQuery不要去处理发送的数据, 发送对象。#}
                      processData : false,
                      {#告诉jQuery不要去设置Content-Type请求头#}
                      contentType : false,
                      async : false,
                      data: formData,
                      success:function (e) {
                          if(e=='1'){
                              layer.msg("成功发布");
                              location.href = "{% url 'article:article_list' %}";
                          }else if(e=='2'){
                              layer.msg("sorry");
                          } else{
                              layer.msg("项目名和内容必须填写");
                          }
                          },
                  });
              }
          </script>
    {% endblock %}

    注意:

      1、由于是post方式提交数据,form中不要忘了{% csrf_token %}

      2、提交按钮是input标签,type="button",千万不要把type=“submit”,否则会导致执行两次后台逻辑

      3、注意文件的取值方式 $('#avatar')[0].files[0],和获取文本方式不太一样,可以在浏览器console中测试验证

      4、文件和文本数据是使用formData存储的

    2、model中需要加上图片字段

    upload_to参数代表将图片文件放在哪里,%Y%m%d是格式化时间,创建一个当天年月日的文件夹,里面放图片文件

    3、修改forms.py

    因为图片也要存入数据库,所以form中也要加上该字段

    4、修改settings.py配置、URL配置

    settings.py中加上媒体文件配置

    # 媒体文件地址
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

    urls.py中加上 

    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

    from django.conf.urls import url, include
    from django.contrib import admin
    from django.conf import settings
    from django.conf.urls.static import static
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^blog/', include('blog.urls', namespace='blog', app_name='blog')),
        url(r'^account/', include('account.urls', namespace='account', app_name='account')),
        url(r'^article/', include('article.urls', namespace='article', app_name='article')),
    ]
    
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

    5、进行数据迁移

    执行python manage.py makemigrations 和 python manage.py migrate进行数据迁移

    6、修改后台代码

    @csrf_exempt
    @login_wrapper
    def article_post(request):
        '''
        文章发布功能
        :param request:
        :return:
        '''
        if request.method == 'POST':
            # print('已进入article_post视图')
            print('request.FILES的值为:%s' % request.FILES)
            print('request.POST的值为:%s' % request.POST)
            # 实例化表单对象,来自于前端ajax请求,由于有文件传输,所以此处加上requesr.FILES
            article_post_form = ArticlePostForm(request.POST, request.FILES)
            if article_post_form.is_valid():
                cd = article_post_form.cleaned_data
                try:
                    # ModelForm 类或者它的子类都具有save()方法,当然实例化后的article_post_form也有此方法,
                    # 它的效果是生成该数据对象,并将表单数据保存到数据库
                    # commit=False则表示只生成文章数据对象,不保存
                    new_article = article_post_form.save(commit=False)
                    # 给该文章数据对象设置作者和栏目后再进行保存
                    new_article.author = request.user
                    new_article.column = request.user.article_column.get(id=request.POST['column_id'])
                    print('正在更新文章到数据库')
                    new_article.avatar = request.FILES.get('avatarrrrr')
                    # avatar = ArticlePost(avatar=request.FILES.get('avatar', None))
                    # print('avatar的值为:%s' % avatar.avatar)
                    # print('request.POST的值为:%s' % request.POST)
                    # print('request.FILES的值为:%s' % request.FILES)
                    # print('request.FILES的值为:%s' % request.FILES.get('avatarrrrr'))
    
                    print('即将保存')
                    new_article.save()
                    print('已经保存啦')
                    return HttpResponse('1')
                except:
                    return HttpResponse('2')
            else:
                return HttpResponse('不合法啊')
        else:
            article_post_form = ArticlePostForm()
            # 获取request.user用户的所有栏目article_column为ArticleColumn模型类中的user字段的related_name,其实等价于
            # article_columns = ArticleColumn.objects.filter(user=request.user)
            # 通过user实例,找到其名下所有的ArticleColumn实例
            article_columns = request.user.article_column.all()
            return render(request, 'article/column/article_post.html', {'article_post_form': article_post_form,
                                                                        'article_columns': article_columns})

     7、测试

  • 相关阅读:
    Tomcat配置
    Tomcat介绍和jbk安装
    nginx企业级优化
    linux 部署lnmp平台
    linux nginx服务
    linux rsync
    openssh远程连接及tcpwrappers防护
    linux 日志文件系统
    linux 解析文件系统原理
    linux 安全配置二
  • 原文地址:https://www.cnblogs.com/gcgc/p/10691316.html
Copyright © 2020-2023  润新知