2017-05-05 37 views
2

来自rails世界,我很高兴地发现mixin。我成立了一个由mixin动态修改而创建的集合

基本混入

核心/ mixins.py

from django.db import models 
from django.contrib.auth.models import User 

class Timestamps(models.Model): 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    class Meta: 
     abstract = True 

然后我Event模型核心/ my_app应用/ models.py

from core import mixins as core_mixins 

class Event(core_mixins.Timestamps): 
    # ... 

所有这些都很好,但如果我想扩展一下并创建一个更动态的mixin,该怎么办?

高级混入

核心/ mixins.py

from django.db import models 
from django.contrib.auth.models import User 

from django.dispatch import receiver 
from django.db.models.signals import pre_save 
from cw_core.requestprovider.signals import get_request 

class Trackable(models.Model): 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    created_by = models.ForeignKey(User, related_name='created_XXX') # <-- ??? 
    updated_by = models.ForeignKey(User, related_name='updated_XXX') # <-- ??? 

    class Meta: 
     abstract = True 

@receiver(pre_save, sender=Event) # <-- ??? 
def security_attributes(sender, instance, **kwargs): 
    request = get_request() 

    instance.updated_by = request.user 

    if instance.id is None: 
     instance.created_by = request.user 

核心/ my_app应用/ models.py

from core import mixins as core_mixins 

class Event(core_mixins.Trackable): 
    # ... 
  • 我将如何动态地设置related_name ?我found this question但我还没有找到我可以在字符串中使用的变量,有没有文档?

  • 此外,我将如何动态设置@receiver调用中的发件人?

我尝试将设置:

@receiver(pre_save, sender=self.__class__) 

但我不能确定这是否行得通呢?建议的方法是什么?

+0

Regariding的'related_name'我发现这个[整齐DOC](https://docs.djangoproject.com/en/1.11/ref/models/options/#default-相关名称) –

回答

2

只需使用现有的功能https://docs.djangoproject.com/en/1.11/topics/db/models/#abstract-related-name

class Trackable(models.Model): 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    created_by = models.ForeignKey(User, related_name='created_%(class)s') 
    updated_by = models.ForeignKey(User, related_name='updated_%(class)s') 
    class Meta: 
     abstract = True 

而对于第二部分也有解决方案https://stackoverflow.com/a/17173716/3627387

@receiver(pre_save) 
def security_attributes(sender, instance, **kwargs): 
    if not issubclass(sender, core_mixins.Trackable): 
     return 
    request = get_request() 

    instance.updated_by = request.user 

    if instance.id is None: 
     instance.created_by = request.user 

基本上你可以过滤信号处理器内部发件人。

另外django-model-utilshttps://django-model-utils.readthedocs.io/en/latest/models.html#timestampedmodel

+0

我从哪里可以得到“get_request”方法?有没有稳定的库提供它? – foobar

+0

@foobar它来自OP的代码'from cw_core.requestprovider.signals import get_request',阅读他的问题。看起来这是他的内部功能 –

+0

@Sardorbek Imomaliev是的,我认为它来自他的代码,但想知道是否有一个库提供这个。这似乎是一个普遍的问题 – foobar