From 1ead8a2a33b208e103306b978e7b8a74872ee374 Mon Sep 17 00:00:00 2001
From: Anup Bagali <anup.bagali1@gmail.com>
Date: Wed, 3 Aug 2022 23:57:33 -0400
Subject: [PATCH] exclude Yourself player from Tournament set

---
 README.md                         |  2 +-
 othello/apps/tournaments/forms.py | 18 +++++++++---------
 othello/settings/__init__.py      |  1 +
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index da660530..7a4089c4 100644
--- a/README.md
+++ b/README.md
@@ -55,7 +55,7 @@ The Othello server uses Ion OAuth, you will need to register an application [her
   * Acceptable hosts can be found in the `ALLOWED_HOSTS` list in `othello/settings/__init__.py`
   * url must be inputted exactly or OAuth will fail
 
-If you are using `docker` to host the Othello services, you will have to manually copy `othello/settings/secret.py.sample` to `othello/settings/secret.py`. If you are using `vagrant`, this is automatically done for you.
+If you are using `docker` to host the Othello services, you will have to manually copy `othello/settings/secret.py.sample` to `othello/settings/secret.py`. If you are using `vagrant`, this is done for you automatically.
 
 After registering an OAuth application enter the key and secret in the `SOCIAL_AUTH_ION_KEY` and `SOCIAL_AUTH_ION_SECRET` variables in `secret.py`
 
diff --git a/othello/apps/tournaments/forms.py b/othello/apps/tournaments/forms.py
index 63937f5f..95214b94 100644
--- a/othello/apps/tournaments/forms.py
+++ b/othello/apps/tournaments/forms.py
@@ -2,6 +2,7 @@
 
 from django import forms
 from django.conf import settings
+from django.contrib.auth import get_user_model
 from django.core.exceptions import ValidationError
 from django.utils import timezone
 
@@ -27,14 +28,17 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
         self.fields["include_users"].label_from_instance = Submission.get_user_name
         self.fields["bye_player"].label_from_instance = Submission.get_user_name
 
+        yourself = get_user_model().objects.get(username="Yourself")
+
+        self.fields["include_users"].queryset = self.fields["include_users"].queryset.exclude(user=yourself)
+        self.fields["bye_player"].queryset = self.fields["bye_player"].queryset.exclude(user=yourself)
+
     def clean(self) -> None:
         cd = self.cleaned_data
         if cd["start_time"] < timezone.now():
             raise ValidationError("A Tournament cannot take place in the past!")
         if cd["include_users"].count() < 2:
             raise ValidationError("A Tournament must include at least 2 players!")
-        if cd["include_users"].filter(user__username="Yourself").exists() or cd["bye_player"].user.username == "Yourself":
-            raise ValidationError('The "Yourself" player cannot participate in Tournaments!')
         if cd["include_users"].filter(id=cd["bye_player"].id).exists():
             raise ValidationError("The bye player cannot participate in the Tournament!")
         if cd["include_users"].filter(is_legacy=True).exists():
@@ -54,6 +58,7 @@ def __init__(self, tournament: Tournament, *args: Any, **kwargs: Any) -> None:
         super(TournamentManagementForm, self).__init__(*args, **kwargs)
         self.tournament = tournament
         self.status = "future" if tournament in Tournament.objects.filter_future() else "in_progress"
+        qs = Submission.objects.latest().exclude(user=get_user_model().objects.get(username="Yourself"))
 
         if self.status == "future":
             self.fields["remove_users"].queryset = tournament.include_users.all()
@@ -67,8 +72,8 @@ def __init__(self, tournament: Tournament, *args: Any, **kwargs: Any) -> None:
 
             self.fields["num_rounds"] = forms.IntegerField(max_value=settings.MAX_ROUND_NUM, required=False)
             self.fields["game_time_limit"] = forms.IntegerField(min_value=1, max_value=15, required=False)
-            self.fields["bye_user"] = forms.ModelChoiceField(queryset=Submission.objects.latest(), required=False)
-            self.fields["add_users"] = forms.ModelMultipleChoiceField(queryset=Submission.objects.latest(), required=False)
+            self.fields["bye_user"] = forms.ModelChoiceField(queryset=qs, required=False)
+            self.fields["add_users"] = forms.ModelMultipleChoiceField(queryset=qs, required=False)
             self.fields["bye_user"].label_from_instance = Submission.get_game_name
             self.fields["add_users"].label_from_instance = Submission.get_game_name
         else:
@@ -85,9 +90,6 @@ def clean(self) -> None:
                 raise ValidationError("Number of rounds must be within 15-60 rounds")
 
             if cd.get("add_users", False):
-                if cd["add_users"].filter(user__username="Yourself").exists():
-                    raise ValidationError('The "Yourself" player cannot participate in Tournaments!')
-
                 if cd.get("bye_user", False):
                     if cd["add_users"].filter(id=cd["bye_user"].id).exists():
                         raise ValidationError("The bye player cannot participate in the Tournament!")
@@ -98,7 +100,5 @@ def clean(self) -> None:
             if cd.get("bye_player", False):
                 if self.tournament.include_users.filter(id=cd["bye_user"].id).exists():
                     raise ValidationError("Cannot set a bye player that is already participating in the Tournament")
-                if cd["bye_user"].user.username == "Yourself":
-                    raise ValidationError('The "Yourself" player cannot participate in Tournaments!')
                 if cd["bye_user"].filter(is_legacy=True).exists():
                     cd["using_legacy"] = True
diff --git a/othello/settings/__init__.py b/othello/settings/__init__.py
index d254da6e..42e6e681 100644
--- a/othello/settings/__init__.py
+++ b/othello/settings/__init__.py
@@ -87,6 +87,7 @@
         "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
     }
 }
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
 
 # Authentication
 AUTH_PASSWORD_VALIDATORS = [