项目总结

来源:互联网 发布:网络骚扰电话怎么拦截 编辑:程序博客网 时间:2024/04/29 17:48

第一天

1.

       svn  版本控制工具,  git也是

2.

       svn  co  http://svn.pyindex.com/testsvn  复制服务器上的内容下来

       svn   st   查看本地和服务器的不同

       svn  add new.txt    添加文件

       ls  -a   在 .svn  中记录了变化

       svn   ci  new.txt   -m   ‘上传的文件’

              上传文件,且加注释

       svn  ci  -m  ‘’  提交所有更改的文件,一般不要用,可能写不进数据库

       svn  up  下载服务器上的内容,只同步不同的内容

       svn  log   提交后日志记录

       svn   log |less   进入编辑器查看,且可进行查找

       svn   up  -r  16   回到版本16

 

svn  del   old.txt   本地删除

       svn   ci  old.txt   -m  ‘ 删除old.txt 文件’

       服务器再删除

svn help  查看命令

       www.subversion.org.cn/tsvndoc/     手册

3.

       [‘1’, ‘2’]+ [‘3’, ‘4’]   返回[‘1’, ‘2’,  ‘3’,  ‘4’]

4.

       a为列表,

              a =a.sort()   a = a.reverse()  a均为None,因此两方法是在本身操作,并没有返回值

5.

       pylint  来检测代码规范性

       字典冒号,右边有空格,左边无空格,与学校的规范不同

       函数名全小写,由下划线连接

       类首字母大写,不适用下划线连接,后面的单词首字母大写

       变量要三个字母以上

       pylint  --generated-members=’objects’  blog/views.py

       检测时中间加此参数,可屏蔽 class 类 has  no  ‘objects’ member  的错误

       pylint  --generate-rcfile  > pylint.conf 生成配置文件

       pylint  --rcfile=pylint.conf   blog/models.py  利用自定义的配置文件来检测

6.

       虽然app放在工程同名的文件下,但是

              AUTH_PROFILE_MODULE=‘appweibo.UserProfile’

       能写’weibo.appweibo.UserProFile’

       重置应用也是

       Python  manage.py  reset  appweibo

       不能写 reset  weibo.appweibo  

   也不能写 reset  weibo/appweibo

       只在setting INSTALLED_APPS中写weibo.appweibo

7.

       自己和好友微博同时按时间排序

       follows=user.get_profile().follow.all()  所有自己关注的人

       show_all_user= list(follows) 将Qset数据变为list

       show_all_user.append(user)   用list的方法添加登录user,到列表中

       weibo_lib_time=[]   用于存放按所有微博时间字符串

       weibo_lib= []  用于存放按发表时间倒序排列的weibo的数据对象

       for  x_user in show_all_user:

              for  x_weibo in x_user.get_profile().weibo.all():

                     weibo_lib_time.append(x_weibo.p_time)

       weibo_lib_time.sort(reverse=True)

       for  time in  weibo_lib_time:

              weibos=x_user.get_profile().weibo.filter(p_time=time)

                     if  weibos:

                            for  weibo in  weibos:

              if weibo.userprofile_set.user in  show_all_user:

                                          weibo_lib.append(weibo)

       8.

              url(r’js/(?P<path>.*)$’, ‘django.views.static.serve’, {‘document_root’:os.path.join(os.path.dirname(__file__), “./templates/js”  ) }, name=’js’ ),

              url(r’css/(?P<path>[\w\.\-]+\.css )$’ ,

      ‘django.views.static.server’ ,

{‘document_root ’:  os.path.join(os.path.dirname(__file__), “./templates/css”)},

name=’css’

),

       url( r’images/(?P<path>[\w\.\-]+\.*)$’ ,

      ‘django.views.static.server’ ,

{‘document_root ’:  os.path.join(os.path.dirname(__file__), “./templates/images”)},

name=’images’

),

此大召不能有中文路径,如工程放在中文桌面下,则会报错

注意r’^images/  前面加’^’错,不能加

将上述三个url加入到urls.py  中  则在模板中使用的图片,css,js 都可以放在与templates目录下的 images,css, js文件夹中,就可已使用了,在引入时直接

<img  href=”images/logo.jpg”  />  即可,不必写”/static/”前缀,也不必将静态文件特意放在setting设置的STATIC_ROOT中。

       url( r’media/(?P<path>[\w\.\-]+\.*)$’ ,

      ‘django.views.static.server’ ,

{‘document_root ’:  os.path.join(os.path.dirname(__file__), “./mymedia”)},

name=’media’

),  再加上这个就可以访问上传到mymedia文件中的图片文件了,注意一般设置MEDIA_URL=’/media/ ’,故要加前缀 ‘/media/’

<img  src=’/media/1.jpg/’ />

 

9.

       HttpResponseRedirect(request.META.get(‘HTTP_REFERER’,  ‘/’)  )

       跳转到提交前的页面。

        如form表单提交到别的url时,执行完再跳转过来,如果form表单提交到当前页面的url,则还是跳到当前,并不会到更之前的页面上

10.

       OneToOne字段,可以相互直接用

              如 class BB(models.Model):

                            aa= models.OneToOne(‘AA’)

                            context= models.CharFIeld(max_length=30)

                     classAA(models.Model):

                            title= models.CharFIeld(max_length=30)

              有  bb= BB.objects.get(id=1)

                     bb.aa.title= ‘test tile’

              有  aa=AA.objects.get(id=1)

                     aa.bb.context=’test  context’

              既互相可以直接访问

11.

       当两个表之间有两个种以上关系时在models中定义是其中一个要加上参数  related_name=’milsetone_task+’   此处’+’老师没写,但手册上有,应该可以不写,不要写+,查询不了了

如果两表只有一种关系时,不要写related_name

例:

Class UserProfile(models.Model):

       Weibo =models.ManyToManyField(‘Weibo’,  related_name=’milestone_task’)  发的微博

       Collect=models.ManyToManyField(‘Weibo’)收藏

       在逆向查询时如果

       weibo =Weibo.objects.create(context=’1111’)

       request.user.get_profile().weibo.add(weibo)

       如果此时只是这样添加的话,虽然关系已经添加进去,但如果如下这样逆向查询的话

       weibo.userprofile_set.all()   为空   []

       因为此时查询的结果为UserProfile collect字段

       此时逆向查询就会遇到问题

       应该这样  weibo.milestone_task.all()即用related_name来代替

userprofile_set

       因此在创建数据,建立关联时要进行两种添加

       所以要将related_name这个参数放在不需要逆向查询的字段

       当定义了related_name”_set”这类查询就被related_name代替,所以用”_set”会报错。

 

12.

       微博全部排序时,因各电脑时间不同,故用id排列不用时间排列

13.

       改头像时

       request.user.userprofile.headimg= newheadimg

request.user.userprofile.save()   是保存不上

       只有:

       userprofile= request.user.userprofile

       userprofile.headimg=newheadimg

       userprofile.save()  才能保存,即用一个变量接受对象进行赋值

14.

               url(r’^index/index$’,  ‘weibo.appweibo.views.index’  , name=’index’)

              在模板中写时,要<a href=’{% url  index%}’> 写name的值

              如果要传参数

              {%url  regist  user.id %} 替代‘/index/index/{{user.id}}’

              如果多个参数{%url regist  username  password%}

15.

       如果主机电脑是192.168.8.15

       Pythonmanage.py  runserver  0.0.0.0 可以在别的电脑

Ip处直接输入 192.168.8.15:8000/index/index可登陆

16.

       图片大小要设双层限制,图片放在的div块要设置大小,img也要设置大小。因有些浏览器不认。

       <div><img/> </div>

                                                 jQuery

1.

       官方下载jquery

       将html文件盒jquery放在同一个文件夹下。

       DOM 对象转换为jQuery对象

       <head>

<!— 在head中引入jQuery -->

<script src=”jquery-1.3.1.js"

type=”text/javascript”> </script>

</head>

<script type="text/javascript">

$(document).ready(function(){ //等待DOM对象加载完成

alert("this is a test."); });    //用来测验jquery是否成功引入

</script>

       这样的转换是简单的,只需要用 $() 符号把

DOM对象包括起来,比如:

       var   check3=document.getElementById(‘id’);

       var   $check3 = $(check3);  

       jQuery 到 DOM对象

       var $check1 = $("#id1"); //定义一个选择框的的jQuery对象

var check1 = $check1[0]; //转换为DOM对象:直接输出

2.

获取id的代表元素的值:

var test1 = $(‘#input_id1’).val();

 给id的元素赋值:

$(‘#input_id2’).val(‘test2’);

 得到id代表的元素的html值:

var test3 = $(‘#div_id3’).html();

给id代表的元素赋予html值:

$(‘#div_id4’).html(“<p> test </p>”);

3.

       单行文本是不能用text()或html()来获取 或者

设置值。必须要用.val() 方法(<textarea><select>也用),它是获取第

一个匹配元素(记住是第一个)的当前值.

html() 是和js  中innerHTML 作用相同,用于<div> <p>等标签

text()  是用来 <textarea>

4.

       $(‘#div1’).html(‘test’)   向id=div1 的标签中写入 ‘test’

       tt = $(‘#div1’).html()   当html()中为空时, 是将其中的内容取出来

5.

       $(‘#one’).css("background", “#bbffaa"): 改变id为one的元素的背景色;

$(‘.mini’).css("background", “#bbffaa"): 改变class为mini的所有元素的

背景色;

$(‘div’).css("background", “#bbffaa"): 改变元素名为div的所有元素

$(‘*’).css("background", “#bbffaa"): 改变所有元素的背景色

基本选择器 1/5: #id

• 描述: 根据给定的id匹配一个元素

• 返回值: 返回单个元素

基本选择器 2/5:.class

• 描述:根据给定的类名匹配元素

• 返回值:集合元素

基本选择器 3/5:element

• 描述:根据给定的元素名匹配元素

• 返回值:集合元素

基本选择器 4/5:*

• 描述:匹配所有的元素

• 返回值:集合元素

基本选择器 5/5:#div1, #div2

• 描述:将每一个选择器匹配到的元素合并

• 返回值:集合元素

$(‘span, #two’).css("background", “#bbffaa"): 改变所有的<span>元素id为two的元素的背景色 ,匹配后的返回值是个集合元素

层次选择器 1/4:$("#div1 h1")  选取id为div1下的所有标签为h1及其所有后代的元素

层次选择器 2/4$("#div1> h1") 选取id为div1下的所有标签为h1并不包含h1中的孙元素

6.

       过滤选择器

 

基本过滤

内容过滤

 

 

 

 

 

可见性过滤

属性过滤

子元素过滤

注上述图片o  为偶数的意思,源于笔误

表单对象属性过滤

表单选择器

7.

       $(document).ready()和window.onload()方法的相似和

区别:

• Window.onload方法是在网页中所有的元素(包括元素的所有关

联文件)完全加载到浏览器后才执行,即javascript此时可以访问

网页的元素;

• 而通过jQuery中的$(document).ready()方法注册的事件处理程

序,在DOM完全就绪时就可以被调用,不需要等到附加的关联文

件都加载好;

• 比如: 有些时候,并不需要图片下载好后,才开始动作,这时候

使用jQuery的 ready()方法,可以使得dom树加载好后,就可以

执行图片的隐藏等

8.

       事件绑定:

              格式:

bind(type,[,data], fn);

• 说明:在文档加载完成后,给元素绑定相应的方法;

• 参数:

• type包含了: blur, focus, load, resize, scroll,

unload,click, dblclick, mousedown, mouseup,

mousemove,mouseover, mouseout,

mouseenter,mouseleave, change  (#select选择变化时) , select,

submit,keydown, keypress, keyup和error等

$(“#pannel h5.head").bind(“click", function(){

$(this).next().show();})

也可以直接调用$("#button").click(function(){alter(‘test’)})

       合成事件-hover():

              hover(enter, leave);

用于模拟光标悬停事件。当光标移动到元素上时,会触发制定

的第一个函数(enter);当光标移出这个元素时,会触发指定

的第二个函数(leave);

例如:

$(“#pannel h5.head").hover(

function() { $(this).next().show(); },

function() { $(this).next().hide();}

);

2 合成事件2-toggle()方法

格式:

toggle(func1, func2, ...funcN);

用于模拟鼠标连续点击事件。第一次点击触发func1;一次类推

示例:

$(function(){

$(“#pannel h5.head").toggle(

function() { $(this).next().show(); },

function() { $(this).next().hide();}

);

})

3.1 动画:show()和hide()方法

• 在HTML代码中,为一个元素调用hide()方法,会

将该元素的display样式改为"none";

• show()方法可以指定一个速度参数

• 示例:

$("element").show("slow");

• $("element").hide(1000); 单位是毫秒

• $("element").show(600);

9.

 jQuery中的Ajax

jQuery中的Ajax分为三个层次:

•底层的是:$.ajax()

•  第二层是:load(), $.get(), $.post()

•第三层是:$.getScript(), $.getJSON()

•其中load()是系统内置函数,”$.”代表全局

函数;第二层的是对底层功能的封装,使用上

较为方便,而底层的功能全面,但是接口较

多,需要查询文档!

10.

       $.get():

格式:$.get(url, data, success(response,status, xhr),dataType)

实例:

$("#button").click(function(){

$.get("ajax.html",

function(result){

alert(result);

} ,

dataType='html'

);

});

$.post():

实例:

$("#button").click(function(){

$.post("ajax.html",{"keys":"text"},

function(result){

alert(result);

});

});

jQuery中的Ajax底层的是:$.ajax(),功能强大,

典型的应用范例是这样的:

$.ajax(

{

 url:"/ajax/exe/?timestamp="+(newDate()).getTime(), 加时间戳,防止局部刷新时从缓存中读取数据。

 type:"POST",

success:function(data){

 $('#div_node').html(data); },

 error:function(){

 $('#div_node').html('<fontcolor="red">对不起,信息

加载失败。请重试或联系管理员。</font>'); }

字典参数

);

其中红色部分是参数;

 $.ajax() 只有一个参数:参数 key/value 对象;

11.

       当然$.get() 等要放在事件中,如click来触发

12

       详细参数见下表:

13.

       如果连不上网

       Vim  /etc/resolv.conf  改为8.8.8.8

       Win7  连接属性选项    使用下面的服务器地址 8.8.8.8

14.

       如果传输失败一般是因为views视图,或views视图return的模板有错误

       瀑布流

<input  type=”hidden” id=”j_var”  value=”0”>

var   j_var = 0; 判断ajax每次只执行一次的指针

if ($(document).height()- $(this).scrollTop() - $(this).height()<100)loadMore();  

  当滚动到最底部以上100像素时, 加载新内容

scrollTop()方法返回或设置匹配元素的滚动条的垂直位置。

$(this).height()返回当前滚动条的长度

 

全部代码:

       var i_flag=0;

       var flag=0;

       $(window).scroll(function){

              if($(document).height()-$(this).scrollTop()- $(this).height()< 50)

                     {

                            if(i_flag ==0){  但数据加载完时,不再回滚

                            window.scrollBy(0,  -100)}   在每次滚动到100下时,都会触发一次load(),  都会触发一次ajax,ajax本身是异步处理数据,所以会导致瀑布流加载的数据乱套。因此此处加此代码:当每次滚动到100以下时,滚动条自动向上回滚100像素,避免了多次ajax触发,此处最好不要用window.scrollTo(0, 100) 因此方法会影响浏览网页,值为坐标,每次都回滚到浏览器的100像素处,会影响用户体验。

       上一段无用,会影响用户体验

                     j_var = $.(“#j_var”).val()  每次执行前取出hidden中的值

                    if(j_var == “0”)(){

                 $.(“#j_var”).val(“1”);   先将指针置1,在执行完本次ajax之前,下次ajax不会启动,

                     最好将此标志放在ajax所在函数外面,因不了解ajax如何异步执行

load();  在指针为0时调用ajax

}

 }   当滚动条到下面100像素时调用load()

}

function load(){

       $.ajax(

              {

                     url:  ‘/add/’ 当此时用到usl传值时 ‘/add/’ +uid+‘/’后面一定要有斜杠

                     type:  ‘POST’ ,

                     dataType: ‘html’,    接收html文件

                     data:{ ‘flag’ : flag } ,

                     success:  function(data){

此处对data的理解,此处veiws返回的是 render_to_response (‘index.html’,{})  此时data得到是个html在模板html中,让模板标签包围所有内容,

{% if   weibos %} <div></div> {% endif%} 或者

{% forweibo  in weibos%}<div></div>   {% endfor%} 当模板标签不成立时,则html标签<div>也就为空了,为下面if(data) 做准备 .注意在子模板html中。开头不能有空格,空格也算内容,就不是空了

       old_data= $(‘#add’).html();

       if(data){flag += 1; }  如果数据库还有数据就使其加一           else{i_flag = 1 };   数据加载完,标志置一,不再回滚, 且注意else与if之间无’ ;此标志位无效,会影响用户体验

       $(‘#add’).html( old_data+data) ;  新旧数据相加实现连续下增数据的效果

       $.(“#j_flag”).val(“0”)  hidden标签来改标志位

} ,

error:function(){ alert(‘failed’) },

}

)

}

在views视图中

def add(request):

       data = ‘’  用来存放响应回去的数据

       flag = request.POST.get(‘flag’)

       flag =int(flag)

       add_notes=Note.objects.all()[6:][flag:flag+1] 先显示6条数据在另一个数据视图方法中渲染进去。 然后此出用来决定没响应以此ajax后增加显示一个数据

              return  render_to_response(‘add_div.html’,  {‘add_notes’: add_notes } ) 将变量数据渲染进add_div.html模板中,在模板中写格式,从而实现格式较好的瀑布流。

15.

       实际上JSON就是Python字典的字符串表示,但是字典作为一个复杂对象是无法直接转换成定义它的代码的字符串,Python有一个叫simplejson的库可以方便的完成JSON的生成和解析,这个包已经包含在Python2.6中,就叫json 主要包含四个方法: dump和dumps(从Python生成JSON),load和loads(解析JSON成Python的数据类型)dump和dumps的唯一区别是dump会生成一个类文件对象,dumps会生成字符串,同理load和loads分别解析类文件对象和字符串格式的JSON

              $.ajax(

                     dataType: ‘json’,    接收json数据,多设置此参数

)

       在views中

              import json

              data = {‘ username’: ‘lufi’, ‘age’:25 }

              data =json.dumps(data)  将字典转化为json数据

              return  HttpResponse(data)

团体项目

1.

       关注 follow  如zhang关注了wang则查询时这样

       wang.userprofile_set.all()   即User逆向查询到User即可。

2.

       Ajax 常犯错误就是id选择时常忘 ’#

       事件  $(“#div1”).click( function(){}注意函数放在括号中

3.

       如果模板中报错,注意是不是 {% url  index %} url漏写了

        如果里面有变量如 {% url  user.id%}  如果变量没有渲染进去的话也会报错,如果url写错了也会报错

4.

       Ajax提交文件 下载 jquery.form.js 并引入

       <form method=’POST’  enctype=’multipart/form-data’  action=’/index/index/’  id=’myForm’>

       {{ photoform }}    仍然将form渲染进去

       <input type=’button’  value=’上传’ id=’bu’ />

       </form>

       <script>

              $(‘#bu’).click(

fuction() {

       $(‘#myForm’).ajaxSubmit(   <form>的id

              dataType:‘html’,

              success:  function(data){ $(‘#content’).html(data) },

              error:function(){alert(‘failed’)},

)

}

)

</script>

       用法和ajax一样,注意调用表单的提交方法 $(‘#myForm’).ajaxSubmit

5.

       在jquery中如果说某个自带的函数不是函数的话,则是jquery的插件没有导入进去,如上面的jquery-form.js

6.

       在form中有布尔值时,如果用的是下拉菜单

       choices=((True, ‘同意’),( False, ‘不同意’))

       时views得到值是字符串 ‘False’ 或者‘True’而不是布尔值

7.

       <embed>  视频图像标签

8.

       实现点图片收藏,变图片,再点再变

       将所有情况在模板上用if写出来,当点一个时,views渲染另一个模板过来,且此模板中也有ajax,即总共三个模板,总模板写两种情况,两个小模板再分别写两个情况,均有ajax

9.

       设置图片大小固定,且不会拉伸图像方法

       <div  id=’div1’ ><img /></div>

       #div1{ width:200px;  height:200px; }  先将图片的外框大小固定

       #div1 img { max-width: 100%; max-height: 90% } 这样会自动根据图像特点来适应外框的大小

10.

              import  datetime

       p_time = models.DateTimeField(default=datetime.datetime.now())

  不要用来做自动保存当前时间的功能,因会将所有时间都统一到runserver运行时的时间,应该在创建数据时,也要给此字段赋值,p_time=datetime.datetime.now()

11.

       <div align=”center”>  实现块内居中

12.

       IE不识别<img   width=”30px”  id=’im1’>

 应该

       <div  id =”k1”><img  id=”k2”/></div>

在style中 

       #k1 { width:80px;  height=80px; display:inline

       #k2 { max-width:  80px; max-height:80px; } 注意此时百分比应该不管用

       如果仍不管专用直接在标签中写

       <img style=”width:80px;height=80px;”>

       但在用bootstap做特效时,有时不能加display:inline。

13.

       在form里clean_data 里提取的数据如value

       在form的 validator=[fun]

fun(value):

       len(value)  如果value是中文,按照一个汉字一个字符串的算法来,

如len(测试)   结果为2

而在普通的python环境下,len(测试) 结果为6

注意  ‘一’  >   ’z’ > ‘Z’

14.

       Queryset数据不能相等

       u1 = User.objects.filter(username=’zhang’)

       u2=User.objects.filter(username=’zhang’)

       print u1=u2  结果为False

15.

       Django布apache时setting要写user,似乎最好还要设置个数据库的密码

16.

        cat  ` find .  –name  *.py `  |wc  -l

       查看代码多少行  注意是左上角的  ``   不是单引号

17

       主要流程参照http://note.sdo.com/u/634799371947687555/n/sBjW3~kjScIG4M088009lL

在第4步上传图片,注意点如下:

1.    在将那40条代码放在与models.py相同目录下的file.py中

2.    在14行‘media’为自己建的domain名,要注意修改

3.    写完file.py 后在models中引入,将原来的FileField  或者ImageField 替换为ZGImageField

4.    在模板访问上传的图片时要写  domain中存储文件的URL全路径如下:

<img src="http://dowia-dowiaimg.stor.sinaapp.com/

{{photo.filename}}" alt="" />

5.MEDIA_ROOT已失去作用,不影响上传

 

附自定义form表单上传文件到storage:

classImageForm(forms.Form):

upfile = forms.FileField()

def  imageUp(request):

 ifrequest.method == 'POST':

b=save_file( request.FILES['upfile'] )

return HttpResponse(b)

imageform = ImageForm()

return render_to_response(

'imageup.html',

{'imageform': imageform}

)

注意如果上传的文件名于storage上已有的文件名相同,则文件不会上传成功。

defsave_file(file1,  path=''):

 filename=str(time.time())+str(random.random())+file1._get_name()

将图片以不同名称存储,最后发现效果是在storage上新建了个以前两个字符串命名的文件夹,文件夹中放了图片原名。

domain_name = "dowiaimg" #申请的domain名

 importsae.storage

 s=sae.storage.Client()

ob = sae.storage.Object(file1.read())

url=s.put(domain_name,  filename,  ob)

return  url

18.

       三秒刷新

       就是 setInterval(‘get_new_data()’,  3000);

       functionget_new_data(){

$.ajax(

{

url: "{% url get_new_data flag xiaozu.id %}", type:'POST',

data: {'new_id': {{weibos.0.id}}},此处微博为按id倒序排列,所以只需取出第一个idviews视图中对比,就可以知道是否有新数据。

dataType : 'html',

success:function(data){

old_data=$('#content1').html(); if(data){$('#content1').html(data); i_var = 0; }

},

error: function(){aa=0},

}

)

 }

views

      new_id = request.POST.get(‘new_id’)

      new_id = int(new_id)

      weibos = Weibo.objects.all()

      weibo = weibos[0]  

      newid = weibo.id

      if new_id == newid:  weiboid倒序排列

          return render_to_response(‘blank.html’, {})

         如果无数据更新,渲染空白网页进去

else:

    cont= {

            “weibos”:  weibos,

}

          return render_to_response(“get_new_data.html”, cont)

注意在get_new_data.html中要用模板标签{% for %}{% endfor %}来包裹全部内容,且{% for %}之前不能有空格

19.

     装python软件

     pip  install  国内源

     easy-insatll    American源

20.

     Sae上传的图片在models重写save方法后,不恩能保存中文名的图片,因此要加个验证

     def  value1(value):

         filename = value.name   注意此处是value.name 而不是value,因为提交的是文件数据对象

         for  x in  xrange(len(filename)):

              if filename[x] > ‘z’:

                       raise  forms.ValidationError(‘图片名不能有中文’)

 

注意如果一个form只有一个字段且是FileField段的话,在绑定是也一定要加上request.POST

     imageform =ImageForm(request.POST,  request.FILES)

原创粉丝点击