None вместо пустого экземпляра Object?

Я пытаюсь создать веб-сайт Secret Santa, используя Python Django. У меня возникает проблема, когда количество участников нечетное. Я использую встроенную в Django модель User и сопоставляю ее экземпляры как совпадения для игры. В случае нечетного количества участников, будет участник без пары. Есть ли способ сохранить None в случае пустого экземпляра без возникновения ValueError?

Вот мой код:

models.py

class Participants (models.Model):
    giver = models.OneToOneField(User, on_delete=models.CASCADE, null = True, blank = True, related_name = "giver")
    receiver = models.OneToOneField(User, on_delete=models.CASCADE, null = True, blank = True, related_name = "receiver")

    def __str__(self):
        return self.receiver.username

views.py

def matchPairs(request):
    participants = User.objects.all().exclude(is_superuser=True)
    participants_names = [p.id for p in participants]
    i = 0
    Givers = []
    Receivers = []
    if request.method == "POST":
        [givers, receivers] = pairs_generator.generate_match(participants_names)
        while i < len(receivers):
            if givers[i] == None:
                Givers.append(None) 
            else:
                Givers.append(User.objects.filter(pk = givers[i]))
            Receivers.append(User.objects.filter(pk = receivers[i]))
            
            Participants.objects.create(giver = Givers[i], receiver = Receivers[i])
            messages.success(request, "Matching successful! Here's the list.")
            return redirect('participants')
    else:
        messages.error(request, "Woops. Something went wrong. Please try again.")
        return redirect('participants')

generate_match.py

def generate_match(participants_names):
    givers = []
    receivers = []
    flag = None
    random.shuffle(participants_names)
    i = 0
    while i < len(participants_names):
      if (is_even(participants_names)):
          print(f'{participants_names[i]} exchanges gifts with {participants_names[i + 1]}. ')
          givers.append(participants_names[i])
          receivers.append(participants_names[i+1])
          i += 2 
      else:
          print(f'{participants_names[i]} has no one to buy a gift to this year. :(')
          givers.append(flag)
          receivers.append(participants_names[i])
          participants_names.pop(i)
    return givers, receivers

Любая помощь или предложение будут полезны.

EDIT Вот трассировка ошибки:

Traceback (most recent call last):
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/fatimavelic/Documents/Doing/projects/penv/santa/secretsanta/views.py", line 44, in matchPairs
    Participants.objects.create(giver = Givers[i], receiver = Receivers[i])
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/db/models/query.py", line 455, in create
    obj = self.model(**kwargs)
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/db/models/base.py", line 489, in __init__
    _setattr(self, field.name, rel_obj)
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 310, in __set__
    super().__set__(instance, value)
  File "/Users/fatimavelic/Documents/Doing/projects/penv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
    raise ValueError(

Exception Type: ValueError at /secretsanta/match-pairs/
Exception Value: Cannot assign "<QuerySet [<User: Daisy>]>": "Participants.receiver" must be a "User" instance.

Queryset.filter возвращает новый объект Queryset. Вместо этого вы хотите использовать Queryset.get(pk=...) или Queryset.filter(...).first(). Вы также можете полностью избежать дополнительных вызовов db, например, проиндексировав всех пользователей по их первичному ключу: id_to_user = {_.pk: _ for _ in participants}

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