我一直在玩django创建一个资产管理应用程序,并在文件上传到模型实例行为方面遇到了障碍。 我试图在Forms.py
中使用ModelForm类基本上我非常确定form.save()没有将我上传的文件写入磁盘来更新我的模型实例。 我是否必须将form.save定义写入AssetForm?或者我错过了别的什么。
感谢任何帮助。
我的项目是围绕民意调查教程https://docs.djangoproject.com/en/1.8/intro/tutorial01/和Need a minimal Django file upload example的最小文件上传教程构建的。
这是我的模特.py
class Category(models.Model):
category_text = models.CharField(max_length=200)
def __str__(self): # __unicode__ on Python 2
return self.category_text
class Asset(models.Model):
asset_text = models.CharField(max_length=200)
asset_tag = models.CharField(max_length=200)
asset_category = models.ForeignKey(Category)
cert_date = models.DateTimeField('cert published')
def __str__(self): # __unicode__ on Python 2
return self.asset_text
def was_certed_recently(self):
return self.cert_date >= timezone.now() - datetime.timedelta(days=365)
was_certed_recently.admin_order_field = 'cert_date'
was_certed_recently.boolean = True
was_certed_recently.short_description = 'Certified recently?'
docfile = models.FileField(upload_to='documents')
这是我的forms.py
from django import forms
from django.forms import ModelForm
from polls.models import Asset
class AssetForm(ModelForm):
class Meta:
model = Asset
fields = '__all__'
这是我的views.py
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.http import HttpResponse
#from django.template import RequestContext, loader
from django.shortcuts import get_object_or_404, render
from django.http import Http404
from polls.models import Asset
from polls.forms import AssetForm
def list(request, asset_id):
# Handle file upload
ID = asset_id
p = get_object_or_404(Asset, pk = asset_id)
if request.method == 'POST':
form = AssetForm(request.POST, request.FILES, instance= p )
if form.is_valid():
form.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('list', args=(p.id,)))
else:
form = AssetForm() # A empty, unbound form
# Load documents for the list page
documents = p
# Render list page with the documents and the form
return render_to_response(
'polls/list.html',
{'documents': documents, 'ID': ID, 'form': form},
context_instance=RequestContext(request )
)
def index(request):
latest_asset_list = Asset.objects.order_by('-cert_date')[:]
context = {'latest_asset_list': latest_asset_list}
return render(request, 'polls/index.html', context)
url.py
from django.conf.urls import url
from . import views
urlpatterns = [
#url(r'^/list/$', 'list', name='list'),
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<asset_id>[0-9]+)/$', views.list, name='list'),
# ex: /polls/5/results/
url(r'^(?P<asset_id>[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<asset_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
最后是我的list.html模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Minimal Django File Upload Example</title>
</head>
<body>
<!-- List of uploaded documents -->
{% if documents %}
<ul>
<p>Current Doc.</p>
<li><a href="{{ documents.docfile.url }}">{{ documents.docfile.name }}</a></li>
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
<ul>
{{ ID }}
<!-- Upload form. Note enctype attribute! -->
<form action="{% url 'list' ID %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
</body>
</html>
答案 0 :(得分:0)
你做了两次各种事情。例如,在您的函数开始时,您将资产转换为p
,然后将相同的资产转换为a
。为什么呢?
更重要的是,在is_valid()
块中,您只是从上传的文件中创建一个新的Asset对象,而没有来自表单的其他数据,但是您保存了应该更新现有资产的表单本身。这可能是导致问题的原因 - 您应该使用docfile
删除这些行,然后只保存表单。