2

首先,一点背景知识:我的医疗保健办公室有一个网络驱动器,我们在其中存储所有患者记录。访问网络驱动器时,默认的 Windows 资源管理器界面无法提供足够的数据安全性。用户可能会意外地重命名事物、移动事物、不正确地命名事物等。发生这种情况时,查找记录变得非常困难。

所以,我试图通过设计一个“更安全”的界面来解决这个问题。我决定使用 Python 和 Django,因为——一旦建立了数据库——它实际上要快得多,而且不必在办公室的每台计算机上都安装应用程序会很好——他们只需访问内部网页。我已经设计了后端 python 代码,它使数据库与网络驱动器保持同步。这并不容易,但我能够弄清楚。但是,现在我必须设计前端,让用户更新数据库,而我没有一个网络程序员,所以仅仅为这个项目学习高级 html、css、jquery 等的想法是令人生畏的。我也很喜欢 Django Admin 界面的外观。最后,它主要完成了我希望它做的事情——提供了一种简单的方法来查看那里的内容,并在必要时进行更改。所以,我决定尝试调整管理模板等,让他们做我想做的事。我遇到了很多问题,但我决定为每个问题单独提出一个问题,这就是我现在正在处理的问题:

每条记录都是一个 pdf,我正在查看 InlineTab 模板并试图让它在本地文件系统上包含指向该 pdf 文件的链接。我已经让它显示一个链接,但是当我点击它时,什么也没有发生。理想情况下,当我点击链接时,我希望它在页面上为该链接留出的空间中显示 pdf(目前每条记录的信息都在整个屏幕上显示,我希望它只在中途显示并让屏幕的其余部分显示所选记录的 pdf),但现在我愿意让链接自行打开。

我的模型:

class Patient(models.Model):
    """Holds all the information needed for a Patient and their records"""
    last_name = models.CharField(max_length = 100)
    first_name = models.CharField(max_length = 100)
    mid_init = models.CharField(max_length = 1, blank = True)
    dob = models.CharField(max_length = 20, blank = True)
    path = models.CharField(max_length = 500, blank = True)

class Record(models.Model):
    "Holds all the information needed for a certain record"""
    patient = models.ForeignKey(Patient)
    title = models.CharField(max_length = 500)
    created = models.CharField(max_length = 20, blank = True)
    path = models.CharField(max_length = 200)

我的“admin.py”:

from django.contrib import admin
from records.models import Patient, Record

class RecordInline(admin.TabularInline):
    model = Record
    extra = 0
    readonly_fields = ['path']

class PatientAdmin(admin.ModelAdmin):
    fieldsets = [
        ('Patient Info',        {'fields': ['last_name', 'first_name', 'mid_init', 'dob']}),
        ('Patient Folder',      {'fields': ['path'], 'classes': ['collapse']}),
    ]
    inlines = [RecordInline]
    list_display = ('last_name', 'first_name', 'mid_init', 'dob')
    search_fields = ('last_name', 'first_name', 'mid_init', 'dob')

admin.site.register(Patient, PatientAdmin)

您可以看到记录被列为“表格内联”,因此我跟踪了该模板(tabular.html),这似乎是该模板的相关部分:

{% if inline_admin_form.original or inline_admin_form.show_url %}<p>
          {% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
          {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
            </p>{% endif %}

这只是显示对象的名称,因此我将其更改为显示指向该对象实际路径的链接(更改的位在 "{% if inline_admin_form.original %}部分中):

{% if inline_admin_form.original or inline_admin_form.show_url %}<p>
          {% if inline_admin_form.original %} <a href="file:///{{ inline_admin_form.original.path }}">{{ inline_admin_form.original.path }}</a>{% endif %}
          {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
            </p>{% endif %}

这肯定给了我一个文件链接,但是当我单击它时,什么也没有发生,当我右键单击并在新选项卡中打开它时,它只会显示“about:blank”。我究竟做错了什么?

更新

部分归功于一些在线研究,以及 ppetrid 在下面的回答,我现在知道我的问题是我正在尝试从 Web 服务器访问本地文件。不是网络程序员,我不知道这会是个问题。不幸的是,我不确定解决方案是什么。

我知道 Django 有一个“文件”对象,使用它似乎很有意义。然而,令人不安的是,以这种方式添加到数据库的每个文件似乎实际上会将文件本身上传到某个位置。问题是我们实际上有数千个文件,大小超过 60GB,基本上复制是行不通的。我想要的只是一个指向文件的指针,以及当一个人点击链接并在他们的浏览器中看到 pdf 时发生的唯一“上传”。文件本身位于网络上的 DLink DNS-325 NAS 设备(我可以在 Django 中的 url 中使用其 IP)。我一直在通过 Windows Map Network Drive 访问它们,因此它们也可以在每个工作站的“Z:/”驱动器下使用。

更新

我发现 Django 本身有一种提供这种类型的“静态”文件的方法。自然,这不适合“生产”,但我会用它来让事情暂时正常工作。我遵循了 Django 网站上关于提供静态文件的说明,并在我的 settings.py 中得到了这个结果:

STATIC_ROOT = 'C:/projects/working/'

STATIC_URL = '/static/'

tabular.html 模板的相应行现在如下所示:

{% if inline_admin_form.original %} <a href="/static/{{ inline_admin_form.original.relative_path }}" target="_blank">{{ inline_admin_form.original.relative_path }}</a>{% endif %}

一方面,这似乎有效,因为它现在正试图打开一个正确的 URL,但无论何时打开,它都会给我一个 404 错误,表明静态文件实际上并未在该位置提供服务。所以,我的新问题是:如何让静态文件在正确的 URL 上实际提供?

另一个更新

好吧,我想我已经取得了突破。似乎虽然 Django 可以提供静态文件,但我并没有采取所有必要的步骤来实现这一点。现在,我的 settings.py 看起来像这样:

STATIC_ROOT = ''

# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    'C:/projects/working/',
)

我的 urls.py 看起来像这样:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^search_results/$', views.search_results),
)

urlpatterns += staticfiles_urlpatterns()

表格内联的模板如下所示:

{% if inline_admin_form.original %} <a href="{% static inline_admin_form.original.relative_path %}" target="_blank">{{ inline_admin_form.original.relative_path }}</a>{% endif %}

现在,这似乎越来越接近我的需要。我没有收到 404、“不存在具有该主键的对象”或当我直接指向硬盘驱动器上的文件时遇到的静默失败。它实际上打开了一个带有正确 URL 的新页面,Chrome 在左下角说“正在加载”(就像打开 pdf 时总是这样),但它只是永远坐在那里。它从未真正加载。还有其他想法吗?

4

1 回答 1

1

为什么要使用 CharField 作为“路径”属性?由于它是一个文件,您应该使用 aFileField来上传 pdf,然后href="{{inline_admin_form.original.path.url}}"获取一个工作链接。

我还将名称从“路径”更改为“pdf”或其他内容。您现在执行此操作的方式是尝试直接从本地文件系统加载文件,这在部署项目后将不起作用(因为文件不会上传到服务器)。您可能还想看看这里https://docs.djangoproject.com/en/dev/topics/files/#using-files-in-models

于 2013-07-30T21:37:12.220 回答