我想在我的django应用程序中为每个模型添加几个字段.这次是created_at,updated_at和notes.20个模型中每个模型的复制代码似乎都很愚蠢.所以,我决定使用抽象基类来添加这些字段.问题是从抽象基类继承的字段首先出现在admin的字段列表中.声明每个ModelAdmin类的字段顺序不是一个选项,它甚至比手动字段声明更重复代码.
在我的最终解决方案中,我修改了模型构造函数以在创建新实例之前重新排序_meta中的字段:
class MyModel(models.Model):
# Service fields
notes = my_fields.NotesField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
last_fields = ("notes", "created_at", "updated_at")
def __init__(self, *args, **kwargs):
new_order = [f.name for f in self._meta.fields]
for field in self.last_fields:
new_order.remove(field)
new_order.append(field)
self._meta._field_name_cache.sort(key=lambda x: new_order.index(x.name))
super(MyModel, self).__init__(*args, **kwargs)
class ModelA(MyModel):
field1 = models.CharField()
field2 = models.CharField()
#etc ...
Run Code Online (Sandbox Code Playgroud)
它按预期工作,但我想知道,有没有更好的方法来实现我的目标?
尝试以最干净的方式向我的应用添加电子邮件通知.当模型的某些字段发生变化时,应该向用户发送通知.这是我的旧解决方案:
from django.contrib.auth import User
class MyModel(models.Model):
user = models.ForeignKey(User)
field_a = models.CharField()
field_b = models.CharField()
def save(self, *args, **kwargs):
old = self.__class__.objects.get(pk=self.pk) if self.pk else None
super(MyModel, self).save(*args, **kwargs)
if old and old.field_b != self.field_b:
self.notify("b-changed")
# Sevelar more events here
# ...
def notify(self, event)
subj, text = self._prepare_notification(event)
send_mail(subj, body, settings.DEFAULT_FROM_EMAIL, [self.user.email], fail_silently=True)
Run Code Online (Sandbox Code Playgroud)
这个工作正常,而我有一两种通知类型,但之后我觉得在我的save()方法中有这么多代码感觉不对.所以,我将代码更改为基于信号:
from django.db.models import signals
def remember_old(sender, instance, **kwargs):
"""pre_save hanlder to save clean copy of original record into `old` attribute
""" …Run Code Online (Sandbox Code Playgroud)