Title: Django Add Edit Form - Field has no attribute assigned to it?
Tags: python;django
Question: Im trying to combine an add and edit form into one and am receiving an error The 'site_image' attribute has no file associated with it.
I could edit files but could not add files, but now when I load the site files page I am receiving the below error, I havent changed the model so am unsure as to why im receiving this error.
the list of files shouldn't really care if site_image is there or not as its set to blank and null?
my file model:
class SiteFiles(models.Model):
site_data = models.ForeignKey(SiteData, verbose_name="Site", on_delete=models.PROTECT)
site_image = models.ImageField(upload_to='site_files/', blank=True, null=True)
site_image_thumbnail = ImageSpecField(source='site_image',
processors=[ResizeToFill(200, 150)],
format='JPEG',
options={'quality': 60})
site_file = models.FileField(blank=True, upload_to=site_files_path, \
validators=[validate_file_extension])
file_name = models.CharField(max_length=200, verbose_name="File Name")
file_type = models.CharField(max_length=100, verbose_name='File Type', \
choices=settings.FILE_TYPE)
class Meta:
verbose_name = "Site Files"
verbose_name_plural = "Site Files"
def __str__(self):
return '%s | %s | %s ' % (self.site_data.location, self.site_data.location, self.file_name)
my forms.py
class FileForm(forms.ModelForm):
class Meta:
model = SiteFiles
fields = ['site_image', 'site_file', 'file_name','file_type']
def __init__(self, *args, **kwargs):
super(FileForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_id = 'file_form'
self.helper.form_method = 'POST'
self.helper.add_input(Submit('submit', 'Save', css_class='btn-primary'))
self.helper.layout = Layout(
Div(
Div(
Div(
Div(HTML('<i class="fa fa-camera-retro fa-fw"&gt;</i&gt; Add File or Photo'), css_class='panel-heading'),
Div(
Field('site_image', placeholder='Image'),
Field('site_file', placeholder='File'),
Field('file_name', placeholder='Display Name'),
Div('file_type', title="File Type"),
css_class='panel-body'
),
css_class='panel panel-default',
),
css_class='col-lg-3'
),
css_class='row'
),
)
my views.py
@login_required
@user_passes_test(lambda u: u.has_perm('sites.add_sitefile'))
def add_edit_file(request, site_id, item_id=None):
from sites.forms import FileForm
from sites.models import SiteFiles
site_data = get_object_or_404(SiteData, pk=site_id)
# set edit values
if item_id:
item_data = get_object_or_404(SiteFiles, pk=item_id)
form_type = 'Edit'
form = FileForm(instance=item_data)
else:
# set add values
form = FileForm()
form_type = 'Add'
item_data = SiteFiles()
# set posting
if request.method == 'POST':
form = FileForm(request.POST,instance=item_data)
if form.is_valid():
form.instance.site_data = site_data
form.save()
return redirect('sites:site_detail_files', site_id)
return render(request, 'sites/add_edit_file.html', {
'add_edit_file_form': form,
'SiteName' : site_data.location,
'SiteID' : site_id,
'ItemID' : item_id,
'FormType' : form_type
})
Error:
Traceback:
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
882.                     current = current[bit]
During handling of the above exception ('ImageFieldFile' object is not subscriptable), another exception occurred:
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
41.             response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _legacy_get_response
249.             response = self._get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
187.                 response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
23.                 return view_func(request, *args, **kwargs)
File "/itapp/itapp/sites/views.py" in site_detail_files
311.         'active_files' : 'class="active"',
File "/usr/local/lib/python3.6/site-packages/django/shortcuts.py" in render
30.     content = loader.render_to_string(template_name, context, request, using=using)
File "/usr/local/lib/python3.6/site-packages/django/template/loader.py" in render_to_string
68.     return template.render(context, request)
File "/usr/local/lib/python3.6/site-packages/django/template/backends/django.py" in render
66.             return self.template.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
207.                     return self._render(context)
File "/usr/local/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
107.     return self.nodelist.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
990.                 bit = node.render_annotated(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
957.             return self.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
177.             return compiled_parent._render(context)
File "/usr/local/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
107.     return self.nodelist.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
990.                 bit = node.render_annotated(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
957.             return self.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
177.             return compiled_parent._render(context)
File "/usr/local/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
107.     return self.nodelist.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
990.                 bit = node.render_annotated(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
957.             return self.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
72.                 result = block.nodelist.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
990.                 bit = node.render_annotated(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
957.             return self.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/defaulttags.py" in render
216.                     nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
957.             return self.render(context)
File "/usr/local/lib/python3.6/site-packages/django/template/library.py" in render
202.         resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
File "/usr/local/lib/python3.6/site-packages/django/template/library.py" in get_resolved_arguments
188.         resolved_args = [var.resolve(context) for var in self.args]
File "/usr/local/lib/python3.6/site-packages/django/template/library.py" in <listcomp&gt;
188.         resolved_args = [var.resolve(context) for var in self.args]
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
708.                 obj = self.var.resolve(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
849.             value = self._resolve_lookup(context)
File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
890.                         current = getattr(current, bit)
File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/files.py" in url
69.         self._require_file()
File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/files.py" in _require_file
46.             raise ValueError("The '%s' attribute has no file associated with it." % self.field.name)
Exception Type: ValueError at /sites/site/files/7
Exception Value: The 'site_image' attribute has no file associated with it.
site_details_files:
@login_required
def site_detail_files(request, site_id):
files = SiteFiles.objects.filter(site_data__id=site_id)
try:
site = files[0].site_data
except:
site = get_object_or_404(SiteData, pk=site_id)
return render(request, 'sites/site_detail_files.html', {
'Files': files,
'SiteName' : site.location,
'SiteID' : site.id,
'PageType' : 'files',
'active_files' : 'class="active"',
})
template:
{% block content %}
<div class="col-lg-9"&gt;
<div class="panel panel-default"&gt;
<div class="panel-heading"&gt;
<i class="fa fa-camera fa-fw"&gt;</i&gt; Photos
</div&gt;
<div class="panel-body"&gt;
{% get_file_type Files 'Cabinet Photo' as photos %}
{% for file in photos %}
<div class="img-item"&gt;
<div class="img"&gt;
<a class="image-float-left" id="" href="{% signed_url file.site_image.url %}" target="_blank"&gt;
<img src="{% signed_url file.site_image_thumbnail.url %}" alt="" /&gt;
</a&gt;
</div&gt;
<div class="img-text"&gt;
{{ file.file_name }}
<div class="img-edit" &gt;
<a href="{% url 'sites:edit_file' SiteID file.id %}" class="edit-icon"&gt;
<i class="fa fa-edit"&gt;</i&gt;
</a&gt;
</div&gt;
</div&gt;
</div&gt;
<!-- /.img-item--&gt;
{% endfor %}
</div&gt;
<!-- /.panel-body--&gt;
</div&gt;
<!-- /.panel--&gt;
</div&gt;
<!-- /.col-lg-9 --&gt;
<div class="col-lg-3"&gt;
<div class="panel panel-default"&gt;
<div class="panel-heading"&gt;
<i class="fa fa-file-text-o fa-fw"&gt;</i&gt; Files
</div&gt;
<div class="panel-body"&gt;
{% exclude_file_type Files 'Cabinet Photo' as site_files %}
{% for file in site_files %}
<ul&gt;
{% if file.file_type != "Cabinet Photo" %}
{% if file.site_file %}
<li&gt;
<a href="{% url 'sites:edit_file' SiteID file.id %}" class="edit-icon"&gt;
<i class="fa fa-edit fa-1x"&gt;</i&gt;
</a&gt;
<a href="{% signed_url file.site_file.url %}" target="_blank"&gt;{{ file.file_name }}</a&gt;
</li&gt;
{% endif %}
{% if file.site_image %}
<li&gt;
<a href="{{% url 'sites:edit_file' SiteID file.id %}" class="edit-icon"&gt;
<i class="fa fa-edit"&gt;</i&gt;
</a&gt;
<a href="{% signed_url file.site_image.url %}" target="_blank"&gt;{{ file.file_name }}</a&gt;
</li&gt;
{% endif %}
{% endif %}
</ul&gt;
{% endfor %}
</div&gt;
<!-- /.panel-body--&gt;
</div&gt;
<!-- /.panel--&gt;
</div&gt;
<!-- /.col-lg-9 --&gt;
{% endblock %}
Comment: "but files are not uploaded anymore" -- that's not enough information to debug. Why are the files not uploaded anymore? If `form.is_valid()` is now `False`, then check `form.errors`.

Comment: I think that's because you are trying to access `file.site_image.url` in the template after you removed `site_image`.

Comment: the fix that you posted and removed has resolved the error but files are not uploaded anymore

Comment: I also deleted all the test files from the DB that I uploaded, I think those had issues

Comment: this issue was fixed with the enctype="multipart/form-data" so two issues fixed, only one left is why site_details_files errors out if I have removed a site_image from a record

Comment: think you're right, I added {% for file in photos %}
{% if file.site_image %} and now the page loads again

Here is the accepted answer: You need to pass request.FILES to the form when uploading files.
form = FileForm(request.POST, request.FILES, instance=item_data)
Make sure that you set enctype="multipart/form-data" in the template as well.
See the docs on file uploads for more info.
However, these changes won't solve your error, since it is coming from a different view site_detail_files. It looks as if you are using file.site_image.url in the template without checking file.site_image first. You should add an extra if block:
{% for file in photos %}
...
{% if file.site_image %}
...
<a class="image-float-left" id="" href="{% signed_url file.site_image.url %}" target="_blank"&gt;
...
{% endif %}
{% endfor %}
Comment for this answer: ok the issue is when I remove a site image from a record it seems, site_details_files added


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 6, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2018:00:01/16/18', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<python><django>', 'Title': 'Django Add Edit Form - Field has no attribute assigned to it?', 'ViewCount': 139, 'id': 48286606, 'user_AboutMe': '', 'user_AccountId': 2611998.0, 'user_DisplayName': 'AlexW', 'user_Reputation': 2533.0, 'user_Views': 593.0, 'user_id': 2261950.0}}