【问题标题】:django auto filling some data based on model attributedjango根据模型属性自动填充一些数据
【发布时间】:2011-01-18 15:09:37
【问题描述】:

我正在研究一个概念,我想在保存模型时捕获某些信息。为了了解全貌,我有一个具有以下模型的应用程序核心

核心/models.py

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from transmeta import TransMeta
from django.utils.translation import ugettext_lazy as _

import signals


class Audit(models.Model):
    ## TODO: Document
    # Polymorphic model using generic relation through DJANGO content type
    operation  = models.CharField(_('Operation'), max_length=40)
    operation_at = models.DateTimeField(_('Operation At'), auto_now_add=True)
    operation_by = models.ForeignKey(User, null=True, blank=True, related_name="%(app_label)s_%(class)s_y+")
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Audit 模型是一种通用的内容类型,目前正在将它与其他应用程序(例如在博客中)附加在一起

博客/models.py

from django.db import models
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
# Create your models here.



    class Meta:
        verbose_name_plural = "Categories"

class article(models.Model):
    title            = models.CharField(max_length=100)
    slug             = models.SlugField(editable=False, unique_for_year=True)
    content          = models.TextField()
    is_active        = models.BooleanField()
    published_at     = models.DateTimeField('Publish at',auto_now=True)
    related_articles = models.ManyToManyField('self', null=True, blank=True)
    audit_obj        = generic.GenericRelation('core.Audit', editable=False, null=True, blank=True)

我的第一次尝试是,我发出了一个 post_save 信号,在该信号中我正在检查实例是否通过包含 audit_obj 属性,然后使用 article.audit_obj.create().save() 保存记录。

不幸的是,这对我来说并没有完全解决,因为我无法传递请求,也无法访问请求以检索用户信息。

所以,我正在考虑创建一个自定义信号并覆盖 form_save 方法(如果有这样的事情),然后使用参数来传递请求对象以及模型对象。

关于如何做到这一点的任何建议?

问候,

编辑(2011 年 1 月 20 日):

感谢@Yuji 抽出宝贵时间。好吧,我想要实现的是让我的代码尽可能干燥。我最终想要做的是,每次创建新模型时,我只会创建一个附加属性并将其命名为 audit_obj,然后我将创建一段代码,要么是一个信号,要么是覆盖 django 核心内部的保存方法。这段代码将始终检查是否存在具有以下名称的属性,因此会在 aduti 表中创建一条记录。

【问题讨论】:

  • 嘿 Mo J.,我在谷歌上搜索一个类似的问题并阅读你的原始帖子(不同的 SO 问题),点击一个链接,然后在帖子中读到我的名字,这真是太奇怪了。希望这对你有用!

标签: python django


【解决方案1】:

我只是在我的模型类或管理器中创建一个函数,然后从我的表单保存中调用它(无论你在哪里)

class AuditManager(models.Manager):
    def save_from_object(self, request, obj):
        audit = Audit()
        audit.object_id = obj.id
        audit.operation_by = request.user
        # ...

        audit.save()


class Audit(models.Model):
    ## TODO: Document
    # Polymorphic model using generic relation through DJANGO content type
    operation  = models.CharField(_('Operation'), max_length=40)
    operation_at = models.DateTimeField(_('Operation At'), auto_now_add=True)
    operation_by = models.ForeignKey(User, null=True, blank=True, related_name="%(app_label)s_%(class)s_y+")
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    objects = AuditManager()


class MyBlogForm(forms.ModelForm):
    class Meta:
        model = article # btw I'd use Capital Letters For Classes

    def save(self, *args, **kwargs):
        super(MyBlogForm, self).save(*args, **kwargs)
        Audit.objects.save_from_object(request, self.instance)

【讨论】:

  • 这也行。但是,我将不得不在每个带有 audit_obj 的模型上重复这段代码。我考虑的方式是创建单个侦听器/信号或覆盖表单保存方法以检查每个操作是否包含 audit_obj 属性,然后在 Audit 类中创建记录。
  • 你能解释一下“或覆盖表单保存方法”部分吗?这不是完全覆盖表单保存方法吗?我认为使它更加干燥的唯一方法是使用覆盖的保存子类化 ModelForm 并在所有表单中使用它。为每个表单创建信号与调用函数(我的示例)的工作相同。没有默认的表单保存信号,所以无论如何你都必须定义它。
  • 谢谢 Yuji,我刚刚对我的原始问题进行了编辑以进行更多说明。
  • 我明白了,这更清楚了。在这种情况下,您可以破解 ModelForms 保存方法以检查相关模型类中的属性(或者如果您将有非模型表单,则可能是 form,并强制将请求传递到表单构造函数中,如果模型/表单具有 audit=是的。不过我真的不喜欢这个想法,至少你应该继承 ModelForms 而不是自己修改它!
猜你喜欢
  • 2021-11-19
  • 2019-10-21
  • 2018-12-22
  • 1970-01-01
  • 2021-12-01
  • 2011-06-14
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
相关资源
最近更新 更多