vag*_*ond 44 django django-models models
我在不同的应用程序中有两个模型:modelA和modelB.他们有一对一的关系.有没有办法在保存modelA时django可以自动创建和保存ModelB?
class ModelA(models.Model):
name = models.CharField(max_length=30)
class ModelB(models.Model):
thing = models.OneToOneField(ModelA, primary_key=True)
num_widgets = IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
当我保存一个新的ModelA时,我希望它的一个条目能够自动保存在ModelB中.我怎样才能做到这一点?有没有办法在ModelA中指定它?或者这是不可能的,我只需要在视图中创建和保存ModelB?
编辑说这些模型在不同的应用程序中.
Joh*_*ett 42
看看django-annoying中的AutoOneToOneField .来自文档:
from annoying.fields import AutoOneToOneField
class MyProfile(models.Model):
user = AutoOneToOneField(User, primary_key=True)
home_page = models.URLField(max_length=255)
icq = models.CharField(max_length=255)
Run Code Online (Sandbox Code Playgroud)
(django-annoying是一个很棒的小库,包括像render_to装饰器和get_object_or_None和get_config函数这样的宝石)
Dmi*_*try 28
与m000指出的一样,您的模型存在于不同的应用程序中.通常您使用未编写的应用程序,因此为了允许更新,您需要一种分离的方式来创建逻辑相关的模型.在我看来,这是首选解决方案,我们在一个非常大的项目中使用它.
通过使用信号:
在你的models.py中:
from django.db.models import signals
def create_model_b(sender, instance, created, **kwargs):
"""Create ModelB for every new ModelA."""
if created:
ModelB.objects.create(thing=instance)
signals.post_save.connect(create_model_b, sender=ModelA, weak=False,
dispatch_uid='models.create_model_b')
Run Code Online (Sandbox Code Playgroud)
如果两个应用程序都是现成的,您可以创建一个单独的应用程序来保存此models.py文件.
Jar*_*die 14
class ModelA(models.Model):
name = models.CharField(max_length=30)
def save(self, force_insert=False, force_update=False):
is_new = self.id is None
super(ModelA, self).save(force_insert, force_update)
if is_new:
ModelB.objects.create(thing=self)
Run Code Online (Sandbox Code Playgroud)
我知道这有点晚了,但我想出了一个更干净、更优雅的解决方案。考虑这个代码:
class ModelA(models.Model):
name = models.CharField(max_length=30)
@classmethod
def get_new(cls):
return cls.objects.create().id
class ModelB(models.Model):
thing = models.OneToOneField(ModelA, primary_key=True, default=ModelA.get_new)
num_widgets = IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
当然你也可以使用 lambda,只要你返回相关对象的整数 id :)
我收集了一些不同的答案(因为没有一个是直接为我工作的)并想出了这个。觉得它很干净,所以我分享了它。
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=ModelA)
def create_modelb(sender, instance, created, **kwargs):
if created:
if not hasattr(instance, 'modelb'):
ModelB.objects.create(thing=instance)
Run Code Online (Sandbox Code Playgroud)
它按照@Dmitry 的建议使用 Signal。正如@daniel-roseman 在@jarret-hardie 的回答中所评论的那样,Django Admin 有时会尝试为您创建相关对象(如果您更改内联表单中的默认值),我遇到了这种情况,因此进行了 hasattr 检查。漂亮的装饰器技巧来自@shadfc在模型创建的 Create OneToOne 实例中的回答
归档时间: |
|
查看次数: |
21318 次 |
最近记录: |