The test class :
class UpadtePadlockTest(TestCase):
username = "testusername"
email = "testuser@name.com"
username2 = "testusername2"
email2 = "testuser2@name.com"
def test_update_padlock(self):
User = get_user_model()
user1 = User.objects.create_user(
self.username, self.email ,
)
user2 = User.objects.create_user(
self.username2, self.email2 , user_locked_with=user1
)
user1.user_locked_with=user2
new_padlock= PadLock.objects.create(start_date=datetime.date(datetime.today()),motto_field="Jodo is my motto",creator=user1,modifier=user2)
response = self.client.post(
reverse('edit_padlock'),
{'start_date':datetime.date(datetime.today()),
'motto_field':"Jodo is not my motto"})
self.assertEqual(response.status_code,302)
new_padlock.refresh_from_db()
self.assertEqual(new_padlock.motto_field,"Jodo is not my motto")
The view that is causing the problem
def edit_padlock(request):
# dictionary for initial data with
# field names as keys
context ={}
user = request.user
# this is the attr that the AnonymousUser is lacking "user_locked_with"
# So filtering users by this attr is not possible
user2 = CustomUser.objects.get(username= user.user_locked_with)
# fetch the object related to passed id
try:
obj = PadLock.objects.get(modifier=request.user)
except Exception:
obj = PadLock.objects.get(creator=request.user)
# pass the object as instance in form
form = PadLockForm(request.POST or None, instance = obj)
# save the data from the form and
# redirect to detail_view
if form.is_valid():
user.lock_published = True
user2.lock_published = True
user.save()
user2.save()
form.save()
try:
padlock = PadLock.objects.get(modifier=request.user)
padlock.active_state = True
padlock.save()
except:
padlock = PadLock.objects.get(creator=request.user)
padlock.active_state = True
padlock.save()
return HttpResponseRedirect("/")
# add form dictionary to context
context["form"] = form
return render(request, "edit_padlock.html", context)
My Custom User :
class CustomUser(AbstractUser):
age= models.PositiveBigIntegerField(null=True,blank=True)
lock_status = models.BooleanField(default=False)
lock_count = models.PositiveIntegerField(default=7,validators=[MaxValueValidator(7),MinValueValidator(0)])
user_is_sender = models.BooleanField(default=False)
user_is_reciever = models.BooleanField(default=False)
user_locked_with = models.CharField(max_length=125,null=True,blank=True)
lock_exist = models.BooleanField(default=False)
lock_published = models.BooleanField(default=False)
The blog post aka the PadLock model :
class PadLock(models.Model):
start_date = models.DateField()
lock_nature = models.TextField(max_length=5,choices=lock_natures,default=story)
motto_field = models.CharField(max_length=200)
story_field = models.TextField(max_length=20000,blank=True ,validators=[MinLengthValidator(4000)])
active_state= models.BooleanField(default=False)
creator = models.OneToOneField(get_user_model(),related_name="creator",on_delete=models.CASCADE,null=True)
modifier = models.OneToOneField(get_user_model(),related_name="modifier",on_delete=models.CASCADE,null=True)
def get_absolute_url(self):
return reverse("padlock_detail", args=[str(self.id)])
I was writing the test for a certain functionality which is modifying a blog post and publishing the post which is referred to as a "padlock" in my code. Should I override the AnonymousUser class ? is there anyway to avoid any unnecessary complications ?
u/Quantra2112 answered the problem on r/djangolearning
You are getting the user from the request and when that user is not authenticated it will be an instance of AnonymousUser. So you can use the login method on the test client: https://docs.djangoproject.com/en/4.2/topics/testing/tools/#django.test.Client.login
You should then also protect your view with the login_required decorator: https://docs.djangoproject.com/en/4.2/topics/auth/default/#the-login-required-decorator
If you don't want to restrict the view to authenticated users I would look for a solution using sessions instead of trying to do anything with the AnonymousUser class. https://docs.djangoproject.com/en/4.2/topics/http/sessions/#module-django.contrib.sessions "
The solution is using the log in method on the client and adding the decorator @login required on the edit_padlock view.