если у вас будут не модели, и вы передадите запрос в конструктор формы, ЕСЛИ модель / форма имеет Audit = True. Мне действительно не нравится эта идея, по крайней мере, вы должны создать подкласс ModelForms вместо того, чтобы изменять его сам!

отаю над концепцией, в которой я хочу получить определенную информацию при сохранении модели. Чтобы понять полную картину, у меня есть ядро ​​приложения со следующей моделью

ядро / 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')

Модель аудита - это тип общего содержимого, в настоящее время я присоединяю его к другим приложениям, таким как в блоге.

блог / 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 (если есть такая вещь), а затем использовать аргументы для передачи объекта запроса, а также объекта модели.

Любой совет, как я могу это сделать?

С Уважением,

РЕДАКТИРОВАТЬ (20 января 2011 г.):

Спасибо @Yuji за ваше время. Что я пытаюсь сделать, так это сохранить мой код максимально сухим. В конечном итоге, что я хочу сделать, каждый раз, когда я создаю новую модель, я только создаю дополнительный атрибут и называю его aud_obj, и я создам отдельный фрагмент кода, либо сигнал, либо переопределение метода save внутри самого ядра django. Часть кода всегда проверяет, существует ли атрибут со следующим именем, и поэтому создает запись в таблице aduti.

 Yuji 'Tomita' Tomita05 окт. 2011 г., 07:49
Привет, Мо Джей. Совершенно странно, что я гуглил похожую проблему и читал твой оригинальный пост (другой вопрос ТАК), нажал на ссылку и прочитал мое имя в посте. Надеюсь, это работает для тебя!

Ответы на вопрос(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)
 Mo J. Mughrabi20 янв. 2011 г., 16:46
Спасибо, Юджи, я только что отредактировал свой оригинальный вопрос, чтобы получить больше разъяснений
 Mo J. Mughrabi18 янв. 2011 г., 21:43
это тоже сработает. Но мне придется повторять этот кусок кода на каждой модели с помощью audit_obj. То, о чем я думал, это создать одного слушателя / сигнала или переопределить метод сохранения формы, чтобы при каждом действии проверять, содержит ли метод атрибут Audit_obj, а затем создавать запись в классе Audit.
 Yuji 'Tomita' Tomita18 янв. 2011 г., 22:08
Можете ли вы объяснить часть «или переопределить метод сохранения формы»? Разве это не переопределяет метод сохранения формы? Я думаю, что единственный способ сделать его более СУХИМым - это создать подкласс ModelForm с переопределенным сохранением и использовать его во всех ваших формах. Создание сигнала для каждой формы - это то же самое, что вызов функции (мой пример). Сигнал сохранения формы по умолчанию отсутствует, так что вам все равно придется его определять.
 Yuji 'Tomita' Tomita20 янв. 2011 г., 18:59
Я вижу, это намного яснее. В этом случае вы можете взломать метод сохранения ModelForms, чтобы проверить наличие атрибута в соответствующем классе модели (или, возможно,form если у вас будут не модели, и вы передадите запрос в конструктор формы, ЕСЛИ модель / форма имеет Audit = True. Мне действительно не нравится эта идея, по крайней мере, вы должны создать подкласс ModelForms вместо того, чтобы изменять его сам!

Ваш ответ на вопрос