2011-01-18 11 views
2

モデル保存時に特定の情報をキャプチャするコンセプトに取り組んでいます。全体像を理解するために、私はモデルの属性に基づいていくつかのデータを自動入力する

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でアプリのコアを持っています

ブログ/ 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) 

、私はインスタンスがaudit_obj属性を含む渡された場合、私がチェックされたpost_save信号を作った私の最初の試みarticle.audit_obj.create().save()を使用してレコードを保存します。

残念ながら、私は要求を受け入れることができず、ユーザー情報を取得する要求にもアクセスできないため、これは完全にうまくいかなかった。

私はカスタム信号を作成し、form_saveメソッドをオーバーライドして(そのようなことがある場合)、引数を使用してリクエストオブジェクトとモデルオブジェクトを渡すことを考えていました。

どのように私はそれを行うことができますか?

よろしく、

EDIT(月、2011年の第20回):

おかげ@Yujiお時間のために。さて、達成しようとしているのは、コードをできるだけDRYに保つことです。最終的に私が最終的にしたいのは、新しいモデルを作成するたびに、追加の属性を作成してaudit_objという名前を付け、信号か、またはdjangoコア自体のsaveメソッドをオーバーライドするコードを作成します。コードの一部は、次の名前の属性が存在するかどうかを常にチェックし、したがってadutiテーブルにレコードを作成します。

+0

のMo J.ねえ、私が同様にグーグルたことを絶対に奇妙ですあなたの元の投稿を読んでいた(別のSOの質問)、リンクをクリックして、私の名前を投稿で読んでいました。それはあなたのために働いていることを願っています! –

答えて

3

私はちょうど私のモデルクラスまたはマネージャで関数を作成して保存私のフォームからそれを呼び出すと思います(あなたがかもしれない場所)

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) 
+0

これもうまくいくでしょう。しかし、私はaudit_objですべてのモデルでこのコードを繰り返さなければなりません。私が考えていたのは、メソッドにaudit_obj属性が含まれていて、その後Auditクラスにレコードを作成する場合、単一のリスナ/シグナルを作成するか、またはフォームのsaveメソッドをオーバーライドしてすべてのアクションをチェックすることです。 –

+0

「フォーム保存メソッドをオーバーライドする」の部分について説明できますか?これは厳密にフォーム保存メソッドをオーバーライドしていませんか?私はそれをもっとDRYにする唯一の方法は、ModelFormをオーバーライドされたセーブでサブクラス化し、それをあなたのすべてのフォームで使うことです。各フォームのシグナルを作成することは、関数を呼び出すことと同じです(私の例)。デフォルトのフォーム保存信号はありませんので、とにかくそれを定義する必要があります。 –

+0

ありがとう、ゆず、私はちょうどより明確にするために私の元の質問を編集しました。 –