Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ForeignKey to AnonymousUser

I would like to follow this guideline and avoid a nullable ForeignKey.

I have a ForeignKey to the django User model.

If I try to store request.user in an instance of this model, I get this error:

ValueError: Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser>>":
 "MyModel.user" must be a "User" instance.

I think it is feasible to avoid the non-conditionless data schema (nullable foreign key).

How could I solve this?

like image 815
guettli Avatar asked Jun 19 '26 04:06

guettli


2 Answers

Those guidelines suggest you create an instance of user that reflects an anonymous user. Otherwise known as a sentinel value. You'd have to keep track of it via some unique key, likely the username. Then make sure it exists and nobody else has actually created a user with that key otherwise you run into other problems.

However, because of those outlined issues above I disagree with those guidelines. If your data model allows for optional relationships, then you absolutely should use NULL values.

Regarding the comment:

If there is no NULL in your data, then there will be no NullPointerException in your source code while processing the data :-)

Simply because there are no NULL fields, doesn't mean those conditions don't exist. You still are handling these edge cases, but changing the names and some of the syntax. You're still vulnerable to bugs because you still have as many conditions (and potentially more given that you have to now make sure your sentinel value is unique).

like image 187
schillingt Avatar answered Jun 22 '26 00:06

schillingt


Hey it's my first attempt at answering a question! I'm a newbie, but I had a similar error recently. I suppose this is a naive version Nigel222's answer which calls for doing this with a migration, but maybe there is something of value here nonetheless for another newbie who needs a simpler solution. I was influenced by an answer to this post by Ayman Al-Absi that suggests that you may need to reference this user by it's auto-generated primary key.

By default, request.user is AnonymousUser when not authenticated. It seems from the error message, AnonymousUser can't be used as value for your foreign key in the User table. Proposed solution:

from django.contrib.auth.models import User
# Start by creating a user in your User table called something like anon in some kind of initialization method:
tempUser= User.objects.create_user(username="anon", email="none", first_name="none", last_name="none")
tempUser.save()
#when the user is unauthenticated, before calling a method that takes request as a parameter do:
if request.user.is_anonymous:
  anonUser = User.objects.get(username='anon')
  request.user=User.objects.get(id=anonUser.id)

Another comment for the newbie. I made my own table called User in models.py. This became confusing. I had to import it with an alias: from .models import User as my_user_table It would have been better just to call it my_user_table to begin with.

like image 22
Nate Avatar answered Jun 21 '26 23:06

Nate



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!