wji*_*jin 12 python django django-models
我是Django的新手,请原谅我的无知:)
假设我有一个具有几个外键关系的模型,当我创建模型的实例时,我希望它自动为外键对象生成新实例.在这种情况下,我将课程注册建模为一个组,我将特定组作为模型上的外键引用.
class Course(models.Model):
student_group = models.OneToOneField(Group, related_name="course_taken")
teacher_group = models.OneToOneField(Group, related_name="course_taught")
def clean(self):
if self.id:
try:
self.student_group
except Group.DoesNotExist:
self.student_group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_student')
try:
self.teacher_group
except Group.DoesNotExist:
self.teacher_group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_teacher')
Run Code Online (Sandbox Code Playgroud)
看起来我可以挂钩模型的干净方法来做到这一点,但我希望能够将整个事情包装在一个事务中,这样如果以后无法创建课程,它就赢了不要创建相关的Group对象.有没有办法实现这个目标?
另外,我在这里做错了吗?Django提供了更好的方法吗?
最终我决定:
from django.db import models, transaction
class Course(models.Model):
student_group = models.OneToOneField(Group, related_name="course_taken")
@transaction.commit_on_success
def save(self, *args, **kwargs):
if not self.student_group_id:
self.student_group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_student')
super(Course, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
编辑(2014/12/01):@Shasanoglu是正确的,上面的代码由于id尚未存在而无法正常工作.在调用save 之后你必须做相关的对象创建(所以你调用super.save,创建相关的对象,更新这个对象并再次调用super.save - 不理想.那或者你从组名中省略了id,它就是精细).但最终,我完全将自动相关对象创建移出了模型.我在自定义表单的保存方法中完成了所有这一切,它更干净,并放弃在管理界面中使用此模型(这就是为什么我坚持在模型方法中首先执行所有这些操作)
您可以使用models.signals.post_save信号来处理这种情况:
from django.db import models
class Course(models.Model):
student_group = models.OneToOneField(Group, related_name="course_taken")
teacher_group = models.OneToOneField(Group, related_name="course_taught")
def create_course_groups(instance, created, raw, **kwargs):
# Ignore fixtures and saves for existing courses.
if not created or raw:
return
if not instance.student_group_id:
group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_student')
instance.student_group = group
if not instance.teacher_group_id:
teacher_group, _ = Group.objects.get_or_create(name='_course_' + self.id + '_teacher')
instance.teacher_group = teacher_group
instance.save()
models.signals.post_save.connect(create_course_groups, sender=Course, dispatch_uid='create_course_groups')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13669 次 |
| 最近记录: |