Django - Обновление только колонки FileField без переопределения других колонок
В Django у меня есть model:
class List(models.Model):
item = models.CharField(max_length=200)
document = models.FileField(upload_to='documents/', null=True, blank=True)
Также у меня есть страница, которая должна ТОЛЬКО загрузить файл в List.document для существующего списка:
В views.py у меня есть
def upload(request, item_id):
if request.method == 'POST':
item = List.objects.get(pk=item_id)
form = ListForm(request.POST, request.FILES, instance=item)
if form.is_valid():
form.save()
messages.success(request, 'File saved successfully.')
else:
messages.error(request, f'File not saved properly: {form.errors.as_data()}')
return redirect('home')
. Однако, поскольку форма не включает List.item, при нажатии Upload возникает ошибка File not saved properly: {'item': [ValidationError(['Это поле обязательно.'])]}.
Самым простым способом может быть добавление List.item в качестве скрытого элемента в html:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="col-md-10">
<input type="file" class="form-control" name="document" />
</div>
<div class="col-md-2">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Upload</button>
</div>
</div>
</form>
Тем не менее, есть ли лучший способ преодолеть это? Может быть, есть варианты, позволяющие не перезаписывать существующие колонки?
Спасибо!
Я проследил за вашей ситуацией, но save() работает хорошо. Ниже приведены коды, которые я тестировал. Вы можете попробовать это.
models.py
from django.db import models
class List(models.Model):
item = models.CharField(max_length=200)
document = models.FileField(upload_to='documents/', null=True, blank=True)
forms.py
from django import forms
from .models import List
class ListForm(forms.ModelForm):
class Meta:
model = List
fields = ['document']
views.py
from django.shortcuts import render, redirect
from .models import List
from .forms import ListForm
# Create your views here.
def upload(request, item_id):
if request.method == 'POST':
item = List.objects.get(pk=item_id)
form = ListForm(request.POST, request.FILES, instance=item)
if form.is_valid():
form.save()
# messages.success(request, 'File saved successfully.')
else:
# messages.error(request, f'File not saved properly: {form.errors.as_data()}')
pass
return redirect('home')
return render(request, 'templates/upload.html', {'form': ListForm()})
upload.html
<!-- both forms are working -->
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form}}
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Upload</button>
</form>
<hr/>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="col-md-10">
<input type="file" class="form-control" name="document" />
</div>
<div class="col-md-2">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Upload</button>
</div>
</div>
</form>
Вместо использования
form = ListForm(request.POST, request.FILES, instance=item)
, я должен использовать
from django.forms import modelform_factory
ListForm_ = modelform_factory(List, fields=("document",))
включать только необходимые поля (т.е. document
).
Спасибо.