【问题标题】:How to save XML safe text data to DB using Django models?如何使用 Django 模型将 XML 安全文本数据保存到数据库?
【发布时间】:2012-10-19 23:25:13
【问题描述】:

我正在构建一个 Django 站点,该站点与应该只保存 XML 安全数据的数据库交互。像 "Mike & Ike" 这样的字符串需要存储为 "Mike & Ike"

据我所知,有两种方法可以解决这个问题。验证表单时,我可以将字符串转换为 XML 安全字符串。对于每个可以包含文本数据的字段,我必须在适当的验证函数中调用xml.sax.saxutils.escape。此外,当从 DB 模型向表单对象提供初始数据时,我必须使用 django.utils.safestring.mark_safe 函数将字符串标记为 safe(模板过滤器,如 |safeautoescape off 在这里没有帮助,因为表单的 html 输出会自动转义所有值)。

class NameForm(forms.Form):
    name = forms.CharField()

    def clean_name(self):
        from xml.sax.saxutils import escape
        return escape(self.cleaned_data['name'])

from django.utils.safestring import mark_safe
form = NameForm(initial={'name': mark_safe(Customer.objects.get(pk=1).name)})

这种方法有缺点。在成为escaped 之后,字符串可能会发生很大变化。另外,我必须记住将所有初始值标记为安全。我认为更好的方法是在数据库保存时转义值,就在值写入数据库之前。它可以让我直接将任何值分配给模型对象,而不必担心转义它们。此外,当从像c = Customer.objects.get(pk=1) 这样的数据库中查找对象时,值c.name 应该是非转义值。例如:

c = Customer(id=1, name="Mike & Ike")
c.full_clean() # "test drive" escaping here and make sure it does not cause field overflow
c.save()
# database now have
# CUSTOMER
# NAME: 'Mike & Ike'
c1=Customer.objects.get(pk=1)
c1.name # Mike & Ike
c.name  # Mike & Ike

这可能吗?我从哪里开始?我已阅读Django documentation,它讨论了保存数据时执行的步骤,但没有关于如何自定义该行为的指南。我想我想自定义那里提到的第 3 步,但我愿意接受建议。任何帮助表示赞赏。

【问题讨论】:

    标签: django django-models django-forms escaping


    【解决方案1】:

    你可以创建一个自定义的save() 方法并在那里转义

    https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods

    例如

    def save(self, *args, **kwargs):
        self.name = clean_name(self.name)
        super(NameForm, self).save(*args, **kwargs)
    

    【讨论】:

    • 我想保存在模型中,与表单无关。我想尽可能晚地进行转义,就在保存之前。我还希望数据库中的值在加载到模型时自动转义。
    • .....据我所知,就是这样。我不清楚你认为调用覆盖保存和超级保存之间会发生什么......
    • 我的示例中的 clean_name 方法将在调用 NameForm.is_valid() 时自动调用。我也没有使用 ModelForms,所以没有保存功能。
    • 这是一个老问题,但我相信@Colleen 给了你你想要的。不要将clean* 方法放入表单中,将它们放入模型中,然后在模型的 save() 覆盖中调用它们,如她所演示的。您可能想致电cleanfull_clean。您的用例在 Django 文档中:You’ll need to call it manually when you want to run one-step model validation for your own manually created models.
    • 我同意这种方法,但我可以看到一个问题:a)您将其绑定到正在执行验证的表单,并且 b)转义函数更改了值,使其不再验证.例如,name = models.CharField(max_length=10) 然后是 form.name = '<b>hi</b>',在尝试保存之前,哪个转义字符会变成 21 个字符。
    猜你喜欢
    • 2016-07-07
    • 2020-07-11
    • 2017-10-11
    • 2013-02-28
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多