我想通过ModelForm上传多个文件,所有文件都分配给Model的file
字段。我已经浏览了文档,我看到了一个示例,我在这里实现了它但我只能让我的表单选择多个文件,但只有一个文件被保存并分配到files
字段。我的代码是
models.py
class Feed(models.Model):
user=models.ForeignKey(User,on_delete=models.CASCADE,related_name='feeds')
text=models.TextField(blank=False,max_length=500)
files = models.FileField(upload_to="files/%Y/%m/%d")
forms.py
class FeedForm(ModelForm):
class Meta:
model=Feed
fields=('text','auth','files')
widgets={"files":forms.FileInput(attrs={'id':'files','required':True,'multiple':True})}
和views.py
def post_feed(request):
form_class = FeedForm
if request.method == 'POST':
form = form_class(request.POST,request.FILES)
if form.is_valid():
feed = form.save(commit=False)
feed.user = User.objects.get(pk=1)
feed.pub_date=timezone.now()
#instance = Feed(files=request.FILES['files'])
# feed.files=request.FILES['files']
feed.save()
return redirect('home')
else:
form = form_class()
return render(request, 'post_feed.html', {'form': form,})
from django.views.generic.edit import FormView
from .forms import FeedForm
class FileFieldView(FormView):
form_class=FeedForm
template_name='post_feed.html'
'''success_url=??? #I dont know what to write here.I thought of putting this
render(request, 'post_feed.html', {'form': form,}) because I just want
to reload the page but it gave an error,so I removed it entirely.'''
def post_feed(self,request,*args,**kwargs):
form_class=self.get_form_class()
form=self.get_form(form_class)
filez=request.FILES.getlist('files')
if form.is_valid():
for f in filez:
f.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
请提前帮助我,谢谢。
答案 0 :(得分:10)
您必须为文件创建单独的模型并使用外键连接它们:
class Feed(models.Model):
user=models.ForeignKey(User, on_delete=models.CASCADE, related_name='feeds')
text=models.TextField(blank=False, max_length=500)
class FeedFile(models.Model):
file = models.FileField(upload_to="files/%Y/%m/%d")
feed = models.ForeignKey(Feed, on_delete=models.CASCADE, related_name='files')
我希望这会有所帮助。
答案 1 :(得分:1)
Ph,我花了整整一天才弄清楚这一点。我的目标是将多个文件分配给一个类的一个实例,例如Blog实例可以具有多个图像。首先,您不能对一个模型(例如,在Blog类中)使用一个models.FileField进行此操作,因为该字段并非旨在保存多个文件。因此,解决方案是为文件创建单独的模型,并通过@Carlos Mermingas的回答将它们与一对多关系(外键)连接。 足够多的话,这是上述情况的代码:
# models.py
class Feed(models.Model):
user=models.ForeignKey(User, on_delete=models.CASCADE)
text=models.TextField(blank=False, max_length=500)
class FeedFile(models.Model):
file = models.FileField(upload_to="files/%Y/%m/%d")
feed = models.ForeignKey(Feed, on_delete=models.CASCADE)
# forms.py
...
from django.forms import ClearableFileInput
...
class FeedModelForm(forms.ModelForm):
class Meta:
model = Feed
fields = ['text']
class FileModelForm(forms.ModelForm):
class Meta:
model = FeedFile
fields = ['file']
widgets = {
'file': ClearableFileInput(attrs={'multiple': True}),
}
# widget is important to upload multiple files
# views.py
from .models import FeedFile
...
def create_to_feed(request):
user = request.user
if request.method == 'POST':
form = FeedModelForm(request.POST)
file_form = FileModelForm(request.POST, request.FILES)
files = request.FILES.getlist('file') #field name in model
if form.is_valid() and file_form.is_valid():
feed_instance = form.save(commit=False)
feed_instance.user = user
feed_instance.save()
for f in files:
file_instance = FeedFile(file=f, feed=feed_instance)
file_instance.save()
else:
form = FeedModelForm()
file_form = FileModelForm()
# the rest is the basic code: template_name, context, render etc.
# in your template.html <form> tag must include enctype="multipart/form-data"
奖金:如果您想在管理面板中查看上传的文件,则可以使用InlineModelAdmin对象。这是代码:
# admin.py of your app
from django.contrib import admin
from .models import Feed, FeedFile
class FeedFileInline(admin.TabularInline):
model = FeedFile
class FeedAdmin(admin.ModelAdmin):
inlines = [
FeedFileInline,
]
admin.site.register(Feed, FeedAdmin)
有关file upload,Model Forms的更多详细信息,如何包含widget in Model Form
答案 2 :(得分:0)
建议使用从char *url = "rtp://127.0.0.1:1234";
AVFormatContext *oc = NULL;
avformat_open_input(&oc, url, NULL , NULL);
模型到Feed
模型的M2M字段。
查询特定FeedFile
对象的文件时更容易,我认为这也是Feed
对象最常用的用例
Feed