繁体   English   中英

如何基于父 model 在另一个 model 中创建 object?

[英]How can I create an object in another model based off parent model?

我在尝试实施(实际上是 map 出来)一个新的 model object 基于父 Z20F35E630DAF49DB88CZ object 时遇到了麻烦。

下面的Bucket model 有一个基于两个category_optionscategory字段。

class Bucket(models.Model):

    category_options = (
        ('personal', 'Personal'),
        ('social', 'Social'),
    )


    class BucketObjects(models.Manager):
        def get_queryset(self):
            return super().get_queryset()

    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='buckets')
    admin_user = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='admin_user')
    guest_user = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='guest_user', blank=True)
    category = models.CharField(max_length=30, choices=category_options)

    ...

    objects = models.Manager()
    bucketobjects = BucketObjects()

    class Meta:
        ordering = ('-created',)

    def save(self, *args, **kwargs):
        if self.stock_list:
            self.stock_count = len(self.stock_list)
            super().save(*args, **kwargs)
        else:
            super().save(*args, **kwargs)

我想在一个完全不同的 model, SocialBucket ,当Bucket model 实例被选择为基于上述category字段的social类别时:

class SocialBucket(models.Model):
    bucket = models.ForeignKey(Bucket.objects.id, on_delete=models.CASCADE, related_name='social_buckets)

我怎样才能 go 关于填充我的SocialBucket model 与基于它的父对象, Bucket , model 的新对象?

编辑:根据要求,这是我将使用的视图:

view.py

class CreateBucket(generics.CreateAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = BucketCreateSerializer
    queryset = Bucket.objects.all()

serializer.py

class BucketCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bucket
        fields = ('owner','category','name','about')
        read_only_fields = ['owner']
    
    def create(self, validated_data):
        user = self.context['request'].user
        bucket = Bucket.objects.create(
         owner=user, 
         **validated_data
        )
        bucket.save()
        return bucket

尝试将models.Model更改为Bucket:

class SocialBucket(Bucket)
    bucket = models.ForeignKey(Bucket.objects.id, on_delete=models.CASCADE, related_name='social_buckets)

我认为最好的方法是使用post_save信号,例如:

from django.db.models.signals import post_save
from django.dispatch import receiver


class Bucket(models.Model):
    ....

class SocialBucket(models.Model):
     bucket = models.ForeignKey(Bucket, on_delete=models.CASCADE, related_name='social_buckets')

@receiver(post_save, sender=Bucket)
def create_social_bucket(sender, instance, created, **kwargs):
    if created and instance.category == 'social':
        SocialBucket.objects.create(bucket=instance)

此外,还有另一种实现方式。 它是从 Bucket model 中覆盖保存方法:

class SocialBucket(models.Model):
    bucket = models.ForeignKey('Bucket', on_delete=models.CASCADE, related_name='social_buckets')  # putting the class of model as a string value to avoid import error

class Bucket(models.Model):
    ....

    def create_social_bucket(self, create_social_bucket=False):
       if create_social_bucket:
           Social.objects.create(bucket_id=self.id)

   def save(self, *args, **kwargs):
       if self.stock_list:
           self.stock_count = len(self.stock_list)
       create_social_bucket = False
       if self.pk is None and self.category == 'social':
           create_social_bucket = True
       super().save(*args, **kwargs)
       self.create_social_bucket(create_social_bucket)

虽然不建议这样做。 您可以破解和硬编码:

class BucketCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bucket
        fields = ('owner','category','name','about')
        read_only_fields = ['owner']
    
    def create(self, validated_data):
        user = self.context['request'].user
        bucket = Bucket.objects.create(
         owner=user, 
         **validated_data
        )
        bucket.save()
        # creating SocialBucket if category is social. You can later update it.
        if bucket.category == 'social':
            social_bucket = SocialBucket()
            social_bucket.bucket = bucket
            social_bucket.save()
        return bucket

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM