Как обновить объект, когда создается несколько других связанных с ним объектов

Мне нужно добавить поле progress_level в мою модель пользователя, которое показывает, на каком этапе находится данный пользователь, поэтому я добавил поле в модель пользователя следующим образом:

progress_level = models.CharField(max_length=25, null=True, choices=USER_PROGRESS_LEVELS)

Я хочу, чтобы это поле автоматически обновлялось каждый раз, когда пользователь выполняет какое-либо действие. Например, если пользователь заполняет контактную информацию и информацию о документе и отправляет форму, уровень прогресса должен измениться на [1][0]. Я действительно не знаю, как это сделать, но я создал сигнал следующим образом:

@receiver(pre_save, sender=User, dispatch_uid='progress_change')
def progress(sender, instance, **kwargs):
    user = instance
    if DocumentInfo.objects.filter(user=user).exists() and ContactInfo.objects.filter(user=user).exists():
        user.progress_level = USER_PROGRESS_LEVELS[1][0]

он работает нормально, но активируется только при сохранении модели User. как я могу предотвратить это? как я могу активировать этот сигнал каждый раз, когда это утверждение истинно? если есть лучший способ сделать это, пожалуйста, помогите мне. Я действительно не знаю, являются ли сигналы правильным способом сделать это.

Как насчет обновления метода сохранения модели?

models.py

class User(...):

    ...
    document_info = models.OneToOneField(DocumentInfo, ...)
    contact_info = models.OneToOneField(ContactInfo, ...)

    def save(self, *args, **kwargs):

        if self.document_info and self.contact_info:
            self.progress_level = USER_PROGRESS_LEVELS[1][0]

        return super().save(*args, **kwargs)

Вы хотите изменить значение progress_level там, где вы добавляете какой-то документ или полный контакт ... как насчет того, чтобы сделать это в методе сохранения или обновления модели документа или модели контакта ... контакт или модель документа, которые связаны с определенным пользователем, имеют метод сохранения или обновления может влиять на значение "progress_level" на модели пользователя через экземпляр пользователя. Вы можете получить экземпляр пользователя из модели документа в методе сохранения (потому что у вас есть внешний ключ) и проверить, что процесс был выполнен... увеличить "progress_level" для экземпляра пользователя. если вы не знаете, как это сделать в коде, дайте мне знать, чтобы я объяснил это на примере кода

Я предполагаю, что ваши модели имеют следующую форму:

class User(AbstractUser):
    progress_level = models.IntegerField(null=True, default=0) 
    // some other field 

class DocumentInfo(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    // some other field

Вы устанавливаете сериализатор для документа следующим образом:

class DocumentInfoSerializer(serializers.ModelSerializer):

    user = UserSerializer(many=False, write_only=True)

    class Meta:
        model = DocumentInfo
        fields = ('id', 'user', /* some other fields */)
        read_only_fields = ('id',)

Теперь в модели DocumentInfo нужно закодировать метод сохранения следующим образом:

class DocumentInfoManager(models.Manager):
    
    def create(self, user, **kwargs):
        user_obj = User.objects.get(id=user.id)            
        user_obj.progress_level = 1 // set progress_level here 
        user.save()                 // user instance update here

        document_obj = DocumentInfo(user=user, **kwargs)
        document_obj.save()

        return document_obj 

class DocumentInfo(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    // some other field
    objects = DocumentInfoManager() // this line is necessary

Вы определяете id в модели User. Обратите внимание, что в модели не обязательно определять поле id (primary_key) с аргументом инкремента ... django создает id для каждой модели автоматически

Вернуться на верх