如何使用 Django Admin 中的 FileField 小部件将文件上传到 BinaryField?

2023-11-25

我想创建一个模型Changelog并使其可从管理页面进行编辑。这是它的定义方式models.py:

class Changelog(models.Model):
    id = models.AutoField(primary_key=True, auto_created=True)
    title = models.TextField()
    description = models.TextField()
    link = models.TextField(null=True, blank=True)
    picture = models.BinaryField(null=True, blank=True)

title and description是必要的,link and picture是可选的。我想让这个模型尽可能简单,所以我选择BinaryField over FileField。在这种情况下,我不需要担心需要备份的单独文件夹,因为数据库将是独立的(我不需要存储文件名或任何其他属性,只需存储图像内容).

我很快意识到,Django Admin 没有一个小部件BinaryField,所以我尝试使用小部件FileField。这是我为实现这一目标所做的事情(admin.py):

class ChangelogForm(forms.ModelForm):

    picture = forms.FileField(required=False)

    def save(self, commit=True):
        if self.cleaned_data.get('picture') is not None:
            data = self.cleaned_data['picture'].file.read()
            self.instance.picture = data
        return self.instance

    def save_m2m(self):
        # FIXME: this function is required by ModelAdmin, otherwise save process will fail
        pass

    class Meta:
        model = Changelog
        fields = ['title', 'description', 'link', 'picture']


class ChangelogAdmin(admin.ModelAdmin):
    form = ChangelogForm

admin.site.register(Changelog, ChangelogAdmin)

正如你所看到的有点老套。您还可以通过子类化创建自己的表单字段forms.FileField,但代码几乎是相同的。它对我来说工作得很好,但现在我在想有没有更好/标准的方法来完成相同的任务?


更好、更标准的方法是创建一个Widget对于这种类型的字段。

class BinaryFileInput(forms.ClearableFileInput):

    def is_initial(self, value):
        """
        Return whether value is considered to be initial value.
        """
        return bool(value)

    def format_value(self, value):
        """Format the size of the value in the db.

        We can't render it's name or url, but we'd like to give some information
        as to wether this file is not empty/corrupt.
        """
        if self.is_initial(value):
            return f'{len(value)} bytes'


    def value_from_datadict(self, data, files, name):
        """Return the file contents so they can be put in the db."""
        upload = super().value_from_datadict(data, files, name)
        if upload:
            return upload.read()

因此,您不必对整个表单进行子类化,只需在需要的地方使用小部件,例如通过以下方式:

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.BinaryField: {'widget': BinaryFileInput()},
    }

正如您已经注意到的,代码大致相同,但这是放置要以特定方式处理的字段的正确位置。实际上,您希望更改一个字段的外观以及在表单中使用时的处理方式,但不需要更改整个表单。

Update

自从写完这个回复以来,Django 引入了一个editable模型上的字段,为了使其正常工作,您需要将模型字段设置为editable=True这是错误的BinaryField默认情况下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Django Admin 中的 FileField 小部件将文件上传到 BinaryField? 的相关文章

随机推荐

  • 将选择下拉箭头替换为 fa-icon

    我试图用 fa 图标 chevron circle down 替换选择下拉箭头 但我只能发现背景可以用 css 文件中的图像替换 我可以在选择上添加图标 但是它不可点击 如何在选择下拉列表中使用字体图标有任何帮助吗 因为你不能使用pseud
  • CTRL+C 忽略 Webbrick 服务器

    In the past I could exit my rails application launched using webbrick using CtrlC At some point in development this func
  • 检查PHP是否已编译--with-mysql [重复]

    这个问题在这里已经有答案了 可能的重复 检测php中的mysql支持 有没有一种快速的方法来以编程方式检查这个特定的 PHP 安装是否已编译为支持 MYSQL 实际上有多个支持 MySQL 的模块 mysql mysqli pdo mysq
  • Spring Boot如何使用jwt进行用户角色管理

    我正在用 spring boot 编写一个 RESTful api 我正在使用 spring boot jersey mongo db swagger spring boot security 和 jwt 我已经编写了模型 数据库请求的存储
  • Android 上的 Web 视图支持 SSL 吗?

    The WebViewandroid 上的控件 支持 SSL 吗 我正在尝试加载一个使用受信任 ssl 证书的网页 但是WebView只是白色的 有什么建议么 不是专家 只是我在网上找到的 据我了解 WebView确实支持ssl 但是 黑屏
  • NPM 不工作(找不到模块“internal/fs”-nodejs)

    更新时出现 NPM 错误 我最近更新到 Node 版本 7 x 现在 npm 不工作了 我无法定位错误 可能是由于 npm ERR Cannot find module internal fs 当我跑步时我得到以下信息sudo npm up
  • 使用 unique_ptr 进行前向声明[重复]

    这个问题在这里已经有答案了 我发现将类的前向声明与std unique ptr如下面的代码所示 它可以使用 GCC 进行编译和工作 但整个事情看起来有点奇怪 我想知道这是否是标准行为 即标准所要求的 由于当我声明时 B 不是完整类型uniq
  • Android使用支持库来支持SearchView

    这是我的代码 if Build VERSION SDK INT gt Build VERSION CODES HONEYCOMB MenuItem searchItem menu findItem R id searchMenuItem S
  • @WebServlet 注释 web.xml 欢迎文件

    我想设置 JSP JavaBeans 项目的欢迎文件 我有一个名为 Controller java 的 servlet 带有以下 WebServlet 注释 WebServlet name Controller urlPatterns lo
  • SetValue 64位机器注册表

    我想在下面的注册表路径中设置 NoModify 的值 HKEY LOCAL MACHINE SOFTWARE Microsoft Windows CurrentVersion Uninstall XXXX 我使用下面的代码 它仅适用于 X8
  • Android Studio 与 Google Play:缺少 Google Play 服务

    我使用的是 Ubuntu 14 Android Studio 0 8 6 我正在使用 Genymotion 运行应用程序 我得到的响应是 W GooglePlayServicesUtil Google Play services is mi
  • 异步 HttpModule MVC

    我有一个包含以下代码的同步 HttpModule
  • Python:无法在 Matplotlib 中渲染 Tex

    我最近将笔记本电脑升级到 Snow Leopard 将 TeX 更新到版本 3 1415926 TeX Live 2011 MacPorts 2011 5 并安装了 Python 2 7 3 所有这些安装完成后 我运行了 macport s
  • Node.js 将响应对象句柄传递给子进程

    我有一个http服务器和一个分叉的子进程 我希望父级接收请求并使用以下方式传递给分叉进程worker send 并且工作人员应该能够使用相同的响应对象处理响应并将其发送回请求者 我尝试在第二个参数中发送响应对象worker send 但它给
  • ASP.NET MVC。检查用户是否获得 JavaScript 授权

    我正在使用 ASP NET MVC Framework 3 和表单身份验证 我知道 如何在服务器端检查用户是否有权执行某些操作 使用 Authorize 并且我知道如何在操作或视图中检查这一点 使用User Identity IsAuthe
  • C++ 是否对 POD typedef 进行值初始化?

    C 是否对简单对象进行值初始化POD类型定义 Assuming typedef T Ptr does Ptr 进行值初始化并保证相等 T 0 e g Ptr p Ptr return Ptr 确实如此 对于一个类型T T 值初始化类型的 对
  • 创建名为“entityManagerFactory”的 bean 时出错 调用 init 方法失败

    我正在使用 Spring 和 Hibernate 开发一个完整的堆栈 Web 应用程序 尝试运行一些测试代码 但我不断收到此错误 这是完整的堆栈跟踪 java lang IllegalStateException Failed to loa
  • 如何在布局中间插入 QWidget?

    我正在使用 Qt 框架来构建我的图形用户界面 我用一个QGrid布局整齐地放置我的 QWidget 图形用户界面如下所示 我的应用程序定期在运行时向 GUI 添加新的小部件 这些新的小部件通常不会添加在 QLayout 的末尾 而是添加在中
  • Android Jetpack Compose 中第二次更改后,观察 LiveData 不会触发

    我正在使用 viewModel 将数据传递到我的撰写视图 问题是我想通过在 viewModel 中的模型内归档来处理展开和折叠视图 因此 如果某些 UI 单击 Expand 方法 我将调用 viewModel 和 doExpand 方法 如
  • 如何使用 Django Admin 中的 FileField 小部件将文件上传到 BinaryField?

    我想创建一个模型Changelog并使其可从管理页面进行编辑 这是它的定义方式models py class Changelog models Model id models AutoField primary key True auto