Django添加编辑表单 - 字段没有分配属性?

时间:2018-01-16 17:19:06

标签: python django

我试图将添加和编辑表单合并为一个并收到错误'site_image'属性没有与之关联的文件。

我可以编辑文件,但无法添加文件,但现在当我加载网站文件页面时,我收到了以下错误,我没有更改模型,因此我不确定为什么我会收到此错误。

如果将site_image设置为空白并且为空,那么文件列表应该不关心吗?

我的文件模型:

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"></i> 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
    })

错误:

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>
  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"',
    })  

模板:

{% block content %}
<div class="col-lg-9">
    <div class="panel panel-default">
        <div class="panel-heading">
            <i class="fa fa-camera fa-fw"></i> Photos
        </div>
        <div class="panel-body">
            {% get_file_type Files 'Cabinet Photo' as photos %} 
            {% for file in photos %}
                <div class="img-item">
                    <div class="img">
                        <a class="image-float-left" id="" href="{% signed_url file.site_image.url %}" target="_blank">
                            <img src="{% signed_url file.site_image_thumbnail.url %}" alt="" />
                        </a>
                    </div>
                    <div class="img-text">
                        {{ file.file_name }}
                        <div class="img-edit" >
                            <a href="{% url 'sites:edit_file' SiteID file.id %}" class="edit-icon">
                                <i class="fa fa-edit"></i>
                            </a>
                        </div>
                    </div>
                </div>
                <!-- /.img-item-->
            {% endfor %}
        </div>
        <!-- /.panel-body-->
    </div>
    <!-- /.panel-->
</div>
<!-- /.col-lg-9 -->
<div class="col-lg-3">
    <div class="panel panel-default">
        <div class="panel-heading">
            <i class="fa fa-file-text-o fa-fw"></i> Files
        </div>
        <div class="panel-body">
                {% exclude_file_type Files 'Cabinet Photo' as site_files %} 
                {% for file in site_files %}
                <ul>
                {% if file.file_type != "Cabinet Photo" %}          
                    {% if file.site_file %}
                    <li>
                        <a href="{% url 'sites:edit_file' SiteID file.id %}" class="edit-icon">
                                <i class="fa fa-edit fa-1x"></i>
                        </a>
                        <a href="{% signed_url file.site_file.url %}" target="_blank">{{ file.file_name }}</a>
                    </li>
                    {% endif %}
                    {% if file.site_image %}
                    <li>
                        <a href="{{% url 'sites:edit_file' SiteID file.id %}" class="edit-icon">
                                <i class="fa fa-edit"></i>
                        </a>
                        <a href="{% signed_url file.site_image.url %}" target="_blank">{{ file.file_name }}</a>
                    </li>
                    {% endif %}
                {% endif %}
                </ul>
            {% endfor %}
        </div>
        <!-- /.panel-body-->
    </div>
    <!-- /.panel-->
</div>
<!-- /.col-lg-9 -->
{% endblock %}

1 个答案:

答案 0 :(得分:1)

上传文件时,您需要将request.FILES传递给表单。

form = FileForm(request.POST, request.FILES, instance=item_data)

确保您也在模板中设置enctype="multipart/form-data"

有关详细信息,请参阅file uploads上的文档。

但是,这些更改不会解决您的错误,因为它来自不同的视图site_detail_files。您似乎在模板中使用file.site_image.url而未先检查file.site_image。你应该添加一个额外的if块:

{% for file in photos %}
    ...
    {% if file.site_image %}
        ...
        <a class="image-float-left" id="" href="{% signed_url file.site_image.url %}" target="_blank">
        ...
    {% endif %}
{% endfor %}