Как получить количество полей, которые либо None, либо пусты в строке, используя ORM Django?

У меня есть модель,

class personal_profile(models.Model):
    custom_user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    picture = models.ImageField(default='pro.png', upload_to='profile_image', blank=True)
    designation = models.CharField(max_length=255, blank=True, null=True)
    gender = models.CharField(max_length=255, blank=True, null=True)
    date_of_birth = models.DateField(blank=True, null=True)
    language = models.CharField(max_length=255, blank=True, null=True)
    linkedin_url = models.CharField(max_length=255, blank=True, null=True)
    def __str__(self):
        return str(self.pk)

Я хочу получить количество полей count, которые либо None, либо "".

personal_profile.objects.get(custom_user=some_user_id)

С помощью приведенного выше запроса я могу получить набор запросов этого конкретного пользователя. Теперь я хочу проверить все поля, принадлежащие этому пользовательскому_пользователю. Например, picture, desgination. gender, date_of_birth, language, linkedin_url

Спасибо

У вас есть два варианта. Вы можете делать подсчет либо на уровне python, либо на уровне базы данных.

Решение #1 Уровень Python

Используйте декоратор @property для подсчета количества пустых полей.

class PersonalProfile(models.Model):
    ...

    @property
    def empty_fields_count(self):
        fields = ["picture", "desgination", "gender", "date_of_birth", "language", "linkedin_url"]
        empty_values = {"", None}
        empty_values_count = 0

        for field in fields:
            field_value = getattr(self, field)
            if field_value in empty_values:
                empty_values_count += 1
        return empty_values_count

И использовать его следующим образом

personal_profile = PersonalProfile.objects.get(custom_user=some_user_id)
# this will return the number of empty fields
personal_profile.empty_fields_count

Решение #2 Уровень базы данных

Используйте annotate для суммирования количества пустых полей

personal_profile_queryset = PersonalProfile.objects.annotate(
    picture_empty=models.Case(
        models.When(models.Q(picture__isnull=True) | models.Q(picture=""), then=1),
        default=0,
    ),
    desgination_empty=models.Case(
        models.When(models.Q(desgination__isnull=True) | models.Q(desgination=""), then=1),
        default=0,
    ),
    gender_empty=models.Case(
        models.When(models.Q(gender__isnull=True) | models.Q(gender=""), then=1),
        default=0,
    ),
    date_of_birth_empty=models.Case(
        models.When(date_of_birth__isnull=True, then=1),
        default=0,
    ),
    language_empty=models.Case(
        models.When(models.Q(language__isnull=True) | models.Q(language =""), then=1),
        default=0,
    ),
    linkedin_url_empty=models.Case(
        models.When(models.Q(linkedin_url__isnull=True) | models.Q(linkedin_url=""), then=1),
        default=0,
    ),
    empty_fields_count=(
        models.F("picture_empty") + 
        models.F("desgination_empty") + 
        models.F("gender_empty") + 
        models.F("date_of_birth_empty") + 
        models.F("language_empty") + 
        models.F("linkedin_url_empty")
    )
)

Затем используйте набор запросов следующим образом

personal_profile = personal_profile_queryset.get(custom_user=some_user_id)
# this will return the number of empty fields
personal_profile.empty_fields_count

Примечания

Возможно, вы захотите переместить коды annotate в пользовательский QuerySet или Manager, если вы хотите повторно использовать кверисет с аннотированным атрибутом empty_fields_count.

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