仅在成功创建其他对象时才创建对象 [英] Create object only if other object is successfully created

查看:17
本文介绍了仅在成功创建其他对象时才创建对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Django 相当陌生,不熟悉这种情况下的最佳实践(在任何框架/语言中,而不仅仅是 python/django).

I am fairly new to Django and unfamiliar with the best practices for this situation (in any framework/language, not just python/django).

这种情况是,当用户第一次在我的网站上注册时,如果组织"不存在,我想为他们创建一个组织",然后为他们创建一个引用该组织的用户.我从不想在没有另一个的情况下插入一个,但我需要先创建组织,以便可以为每个用户保存组织 UUID.现在,即使创建用户存在问题,组织仍将被创建.这显然是一个问题,因为那时我有一个没有附加用户的组织.

The situation is that when a user first registers on my site, I want to create an "organization" for them if it doesn't exists, and then subsequently create a user for them, which references the organization. I never want to insert one without the other, but I need to create the organization first so that the organization UUID can be saved for each user. Right now, organizations will still be created even if there is an issue with the creation of the user. This is obviously a problem because then I have an organization with no users attached.

我不完全知道如何在创建组织之前检查是否正确创建了用户,但我需要按照这些思路进行操作.在组织对象创建上使用 commit=false 似乎不起作用,因为我需要获取 UUID.所以我不确定继续的最佳方式.

I don't exactly know how to check that the user will be properly created before creating the organization, but something along these lines seems to be what I need to do. Using commit=false on the organization object creation wouldn't seem to work because I need to get the UUID. So I am not sure the best way to proceed.

我正在覆盖流行的身份验证包 django-allauth 的序列化程序中的 save 方法

I am overwriting the save method in the serializer of the popular authentication package django-allauth

class Organization(models.Model):
  alphanumeric_plus_underscore = RegexValidator(r'^[w]+$', 'Only alphanumeric characters are allowed.')
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)  # pylint: disable=invalid-name
  name = models.CharField(max_length=20, unique=True, validators=[alphanumeric_plus_underscore, MinLengthValidator(4)])
  logo = models.FileField(upload_to='files/organization_logos/', null=True, blank=True)

class User(AbstractBaseUser):
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)  # pylint: disable=invalid-name
  first_name = models.CharField(_('First Name'), max_length=50)
  last_name = models.CharField(_('Last Name'), max_length=50)
  email = models.EmailField(_('Email address'), unique=True)
  organization = models.ForeignKey(Organization, blank=False, null=False, on_delete=models.DO_NOTHING)

serializers.py

def save(self, request):
    # generate organization object
    organization_data = self.validated_data.pop('organization')
    organization = Organization.objects.create(**organization_data)
    self.validated_data['organization'] = organization

    adapter = get_adapter()
    user = adapter.new_user(request)
    self.cleaned_data = self.get_cleaned_data()
    user.organization = organization #self.cleaned_data.get('organization')
    adapter.save_user(request, user, self)
    self.custom_signup(request, user)
    setup_user_email(request, user, [])

    return user

非常感谢任何指导.

推荐答案

原子性是数据库事务的定义属性.atomic 允许我们创建一个代码块,在其中保证数据库的原子性.如果代码块成功完成,更改将提交到数据库.如果出现异常,则回滚更改.

Atomicity is the defining property of database transactions. atomic allows us to create a block of code within which the atomicity on the database is guaranteed. If the block of code is successfully completed, the changes are committed to the database. If there is an exception, the changes are rolled back.

from django.db import transaction

def viewfunc(request):
    # This code executes in autocommit mode (Django's default).
    do_stuff()

    with transaction.atomic():
        # This code executes inside a transaction.
        do_more_stuff()

更多细节参考到给定的链接.

for more detail refer to the given link.

这篇关于仅在成功创建其他对象时才创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆