Reputation: 1798
I have a model like this:
class Assignment(models.Model):
content = models.FileField(upload_to='xxx')
other_val = models.CharField(...) # not important
And a form wrapping this model (ModelForm):
class AssignmentForm(ModelForm):
class Meta:
model = Assignment
fields = ['content', 'other_val']
My view looks like this (for simplicity I skip the request.POST/request.FILES. part):
@login_required(login_url='/login/')
def create_assignment(request):
form = AssignmentForm()
# render form
@login_required(login_url='/login/')
def update_assignment(request, assignment_id):
assignment = Assignment.objects.get(id=assignment_id)
form = AssignmentForm(instance=assignment)
Creating an assignment works just fine - It forces me to upload a file, which is what I want. But when I want to update the content of the assignment (the file), it first shows a link of a previously uploaded file (excellent!) then the upload button, like this:
Currently: AssignmentTask_grading_script/grading_script_firing.py
Change: [Choose File] no file chosen
But then I assume if I don't want to replace this file, I should simply click the submit button. Unfortunately, when I click the submit button, the form complains that I should upload a file. Is there a way to silent the complaint if a file is already in database?
Upvotes: 0
Views: 1256
Reputation: 11
If someone stumbles upon this question again... The easiest pythonic way is to edit the form init method instead: for given example in the Question:
class Assignment(models.Model):
content = models.FileField(upload_to='xxx')
other_val = models.CharField(...) # not important
class AssignmentForm(ModelForm):
class Meta:
model = Assignment
fields = ['content', 'other_val']
def __init__(self, *args, **kwargs):
super(AssignmentForm, self).__init__(*args, **kwargs)
if self.instance.content:
self.fields['content'].widget.attrs.pop('required', None)
But if the model has following setup (FileField is allowed to be empty):
class Assignment(models.Model):
content = models.FileField(upload_to='xxx', null=True, blank=True)
other_val = models.CharField(...) # not important
class AssignmentForm(ModelForm):
class Meta:
model = Assignment
fields = ['content', 'other_val']
def __init__(self, *args, **kwargs):
super(AssignmentForm, self).__init__(*args, **kwargs)
if not self.instance.content:
self.fields['content'].widget.attrs['required'] = 'required'
In this case the Form Class is rendered by django without an instance (creating a new database entry) so the FileField will be mandatory.
Upvotes: 0
Reputation: 4194
As following the previous comments, maybe like this;
1. forms.py
class AssignmentForm(forms.ModelForm):
# as following @Rohan, to make it optional.
content = forms.FileField(required=False)
class Meta:
model = Assignment
fields = ['content', 'other_val']
2. yourtemplate.html
<form method="post" enctype="multipart/form-data" action=".">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
<script>
{% if not form.content.value %}
$('#id_content').attr({'required': 'required'});
{% endif %}
</script>
The field of
content
is under required only if havn't value before...
Upvotes: 1