RelatedObjectDoesNotExist: User has no userprofile

后端 未结 7 1033
旧巷少年郎
旧巷少年郎 2020-12-28 17:58

So I\'ve extended my user with the field score like this:

models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(Us         


        
相关标签:
7条回答
  • 2020-12-28 18:24

    Answering your updated question. There is already a save() method in models and it gets called every time you save a model (in your case when you call create_user()). So all you need to do is define a handler function and connect it to the post_save signal.

    def create_extension(sender, instance, created, *args, **kwargs):
        if created:
            # do your thing
    
    models.signals.post_save.connect(create_extension, sender=User, dispatch_uid='create_extension')
    

    I usually put the handler functions into a separate file signals.py and add connect() statements at the end of models.py

    0 讨论(0)
  • 2020-12-28 18:29

    You have to create a userprofile for the user first:

    profile = UserProfile.objects.create(user=request.user)
    

    In your views.py you can use get_or_create so that a userprofile is created for a user if the user doesn't have one.

    player, created = UserProfile.objects.get_or_create(user=request.user)
    

    UPDATE: For automatically creating user profiles every time a new user is made, use singals. In myapp/signals.py do something like this:

    @receiver(post_save, sender=User, dispatch_uid='save_new_user_profile')
    def save_profile(sender, instance, created, **kwargs):
        user = instance
        if created:
            profile = UserProfile(user=user)
            profile.save()
    
    0 讨论(0)
  • 2020-12-28 18:29

    If you are getting this error even if you've tried the suggestions above, it may caused by the fact that the first user you had created (with createsuperuser command) does not have a profile.

    I was getting this error when I tried to login with that user. I solved it this way:

    -Create a new user.

    -Undo the changes. (Erase the code you've written for Profile or make them comment lines)

    -Log in to your superuser.

    -Give admin authorization to newly created user.

    Now you can delete the first user. (The user with no profile)

    0 讨论(0)
  • 2020-12-28 18:33

    I'm a bit kinda late for this but ill just, share the solution that worked for me on Django 3.0.8...

    Error : RelatedObjectDoesNotExist: User has no profile

    This the is where my error was directing me to :

    @login_required
    def dashboard(request):
        if request.method == 'POST':
            user_form = UserEditForm(instance=request.user, data=request.POST)
            profile_form = ProfileEditForm(instance=request.user.profile, data=request.POST, files=request.FILES)
    

    Note: You have to login or your profile to be saved.

    Just after creating your account, you should be able to see that you are not logged in and you will have to log in to for your profile be saved and to start working.

    0 讨论(0)
  • 2020-12-28 18:40

    Just try to create a new user using shell to get access to the admin page then create a profile from admin page for the old user : python manage.py createsuperuser

    To access to shell, inside your directory project ine terminall type : python manage.py shell

    0 讨论(0)
  • 2020-12-28 18:41

    Nothing in what you've done forces the creation of a UserProfile object when a User is created. There are two basic ways of handling this:

    1. If you always want a UserProfile to exist (which seems like the case as you give a default value to score, create a post_save handler that creates a new profile when ever the User object is created (but not every time it's saved, so make sure to check the created argument in the handler).

    2. If it's expected a user may not have a profile, you need to catch the UserProfile.DoesNotExist exception when trying to access it. If you do this frequently, make some kind of helper function.

    UPDATED TO ANSWER SIGNAL QUESTION

    It also looks like somewhere around here post_save.connect(create_profile, sender=User) should be added?

    You would need to define a function called create_profile and then wire it up as you have shown. I typically do this right in the models.py file that includes the sender but in this case where the sender is a built-in Django model and you're already importing that model into the file where you define your UserProfile that's the place to do it. It would look something like:

    def create_profile(sender, instance, created, *args, **kwargs):
        # ignore if this is an existing User
        if not created:
            return
        UserProfile.objects.create(user=instance)
    post_save.connect(create_profile, sender=User)
    
    0 讨论(0)
提交回复
热议问题