Django models.py OneToOneField — help creating a relationship between two models





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I am having trouble testing a relationship between two models (CustomUser and Profile) located in different apps. I'm hoping someone can identify where I am going wrong here:



Here is my profiles/models.py --- you can see my user field attempting to create a OneToOne with with my users/models.py:



from django.db import models

from core.models import TimeStampedModel

class Profile(TimeStampedModel):
user = models.OneToOneField('users.CustomUser', on_delete=models.CASCADE)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
bio = models.TextField(blank=True)
image = models.URLField(blank=True)

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


Here is my users/models.py:



class CustomUser(AbstractBaseUser, PermissionsMixin, TimeStampedModel):
username = models.CharField(db_index=True, max_length=255, unique=True)
email = models.EmailField(db_index=True, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_provider = models.BooleanField(default=False)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

objects = CustomUserManager()

def __str__(self):
return self.email

@property
def token(self):
return self._generate_jwt_token()

def get_short_name(self):
return self.username

def _generate_jwt_token(self):
dt = datetime.now() + timedelta(days=60)

token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')

return token.decode('utf-8')


So the idea is that when I create a new user, a profile is automatically created as well. To do this, I am using a post_save signal in my users app:



users/signals.py:



from django.db.models.signals import post_save
from django.dispatch import receiver

from conduit.apps.profiles.models import Profile

from .models import User

@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created:
instance.profile = Profile.objects.create(user=instance)


And finally an update to my users/init.py file:



from django.apps import AppConfig


class UsersAppConfig(AppConfig):
name = 'django.users'
label = 'users'
verbose_name = 'Users'

def ready(self):
import users.signals

default_app_config = 'django.users.UsersAppConfig'


That last update is something I am relatively unfamiliar with. I suspect this is where my problem is located.



I am able to resister a new user via an api call with no problem, however, when I test to see if a Profile object exists for that new user, I am left with the following error:



python manage.py shell

from users.models import CustomUser

u = CustomerUser.objects.last()

u
<CustomUser:testuser@gmail.com> --- everything works to this point

u.profile --- this is where it breaks down


I'm left with this error in shell:



users.models.CustomUser.profile.RelatedObjectDoesNotExist: CustomUser has no profile.


Any help would be appreciated, thanks!










share|improve this question























  • Can you show how you create your users (i.e. how was u created in your example above)? Also, I believe your init.py file should be named __init__.py instead (two underscores before and after). This is typical Python convention...

    – Jonah Bishop
    Nov 27 '18 at 1:28













  • The init.py is not the issue. It looks like I had originally typed that, but the double underscores passed some unwanted markdown on my text. The 'u' object was created from my CustomUser model. You can see that imported during my shell session. Above that, you can see my actual CustomUser model. I left out the CustomerUserManager for the sake of brevity.

    – Andy G
    Nov 27 '18 at 1:33











  • You did call the save() routine to create your user instance though, correct? If you used something like bulk_create(), the save() routine gets bypassed, which means your signals won't fire.

    – Jonah Bishop
    Nov 27 '18 at 1:36











  • Yes, I believe so. Prior to extending the AbstractBaseUser in my CustomUser model, I defined a create_user and create_superuser function where I explicitly make a user.save() call before returning user. I'm investigating this more.

    – Andy G
    Nov 27 '18 at 1:58


















1















I am having trouble testing a relationship between two models (CustomUser and Profile) located in different apps. I'm hoping someone can identify where I am going wrong here:



Here is my profiles/models.py --- you can see my user field attempting to create a OneToOne with with my users/models.py:



from django.db import models

from core.models import TimeStampedModel

class Profile(TimeStampedModel):
user = models.OneToOneField('users.CustomUser', on_delete=models.CASCADE)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
bio = models.TextField(blank=True)
image = models.URLField(blank=True)

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


Here is my users/models.py:



class CustomUser(AbstractBaseUser, PermissionsMixin, TimeStampedModel):
username = models.CharField(db_index=True, max_length=255, unique=True)
email = models.EmailField(db_index=True, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_provider = models.BooleanField(default=False)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

objects = CustomUserManager()

def __str__(self):
return self.email

@property
def token(self):
return self._generate_jwt_token()

def get_short_name(self):
return self.username

def _generate_jwt_token(self):
dt = datetime.now() + timedelta(days=60)

token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')

return token.decode('utf-8')


So the idea is that when I create a new user, a profile is automatically created as well. To do this, I am using a post_save signal in my users app:



users/signals.py:



from django.db.models.signals import post_save
from django.dispatch import receiver

from conduit.apps.profiles.models import Profile

from .models import User

@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created:
instance.profile = Profile.objects.create(user=instance)


And finally an update to my users/init.py file:



from django.apps import AppConfig


class UsersAppConfig(AppConfig):
name = 'django.users'
label = 'users'
verbose_name = 'Users'

def ready(self):
import users.signals

default_app_config = 'django.users.UsersAppConfig'


That last update is something I am relatively unfamiliar with. I suspect this is where my problem is located.



I am able to resister a new user via an api call with no problem, however, when I test to see if a Profile object exists for that new user, I am left with the following error:



python manage.py shell

from users.models import CustomUser

u = CustomerUser.objects.last()

u
<CustomUser:testuser@gmail.com> --- everything works to this point

u.profile --- this is where it breaks down


I'm left with this error in shell:



users.models.CustomUser.profile.RelatedObjectDoesNotExist: CustomUser has no profile.


Any help would be appreciated, thanks!










share|improve this question























  • Can you show how you create your users (i.e. how was u created in your example above)? Also, I believe your init.py file should be named __init__.py instead (two underscores before and after). This is typical Python convention...

    – Jonah Bishop
    Nov 27 '18 at 1:28













  • The init.py is not the issue. It looks like I had originally typed that, but the double underscores passed some unwanted markdown on my text. The 'u' object was created from my CustomUser model. You can see that imported during my shell session. Above that, you can see my actual CustomUser model. I left out the CustomerUserManager for the sake of brevity.

    – Andy G
    Nov 27 '18 at 1:33











  • You did call the save() routine to create your user instance though, correct? If you used something like bulk_create(), the save() routine gets bypassed, which means your signals won't fire.

    – Jonah Bishop
    Nov 27 '18 at 1:36











  • Yes, I believe so. Prior to extending the AbstractBaseUser in my CustomUser model, I defined a create_user and create_superuser function where I explicitly make a user.save() call before returning user. I'm investigating this more.

    – Andy G
    Nov 27 '18 at 1:58














1












1








1








I am having trouble testing a relationship between two models (CustomUser and Profile) located in different apps. I'm hoping someone can identify where I am going wrong here:



Here is my profiles/models.py --- you can see my user field attempting to create a OneToOne with with my users/models.py:



from django.db import models

from core.models import TimeStampedModel

class Profile(TimeStampedModel):
user = models.OneToOneField('users.CustomUser', on_delete=models.CASCADE)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
bio = models.TextField(blank=True)
image = models.URLField(blank=True)

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


Here is my users/models.py:



class CustomUser(AbstractBaseUser, PermissionsMixin, TimeStampedModel):
username = models.CharField(db_index=True, max_length=255, unique=True)
email = models.EmailField(db_index=True, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_provider = models.BooleanField(default=False)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

objects = CustomUserManager()

def __str__(self):
return self.email

@property
def token(self):
return self._generate_jwt_token()

def get_short_name(self):
return self.username

def _generate_jwt_token(self):
dt = datetime.now() + timedelta(days=60)

token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')

return token.decode('utf-8')


So the idea is that when I create a new user, a profile is automatically created as well. To do this, I am using a post_save signal in my users app:



users/signals.py:



from django.db.models.signals import post_save
from django.dispatch import receiver

from conduit.apps.profiles.models import Profile

from .models import User

@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created:
instance.profile = Profile.objects.create(user=instance)


And finally an update to my users/init.py file:



from django.apps import AppConfig


class UsersAppConfig(AppConfig):
name = 'django.users'
label = 'users'
verbose_name = 'Users'

def ready(self):
import users.signals

default_app_config = 'django.users.UsersAppConfig'


That last update is something I am relatively unfamiliar with. I suspect this is where my problem is located.



I am able to resister a new user via an api call with no problem, however, when I test to see if a Profile object exists for that new user, I am left with the following error:



python manage.py shell

from users.models import CustomUser

u = CustomerUser.objects.last()

u
<CustomUser:testuser@gmail.com> --- everything works to this point

u.profile --- this is where it breaks down


I'm left with this error in shell:



users.models.CustomUser.profile.RelatedObjectDoesNotExist: CustomUser has no profile.


Any help would be appreciated, thanks!










share|improve this question














I am having trouble testing a relationship between two models (CustomUser and Profile) located in different apps. I'm hoping someone can identify where I am going wrong here:



Here is my profiles/models.py --- you can see my user field attempting to create a OneToOne with with my users/models.py:



from django.db import models

from core.models import TimeStampedModel

class Profile(TimeStampedModel):
user = models.OneToOneField('users.CustomUser', on_delete=models.CASCADE)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
bio = models.TextField(blank=True)
image = models.URLField(blank=True)

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


Here is my users/models.py:



class CustomUser(AbstractBaseUser, PermissionsMixin, TimeStampedModel):
username = models.CharField(db_index=True, max_length=255, unique=True)
email = models.EmailField(db_index=True, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_provider = models.BooleanField(default=False)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

objects = CustomUserManager()

def __str__(self):
return self.email

@property
def token(self):
return self._generate_jwt_token()

def get_short_name(self):
return self.username

def _generate_jwt_token(self):
dt = datetime.now() + timedelta(days=60)

token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')

return token.decode('utf-8')


So the idea is that when I create a new user, a profile is automatically created as well. To do this, I am using a post_save signal in my users app:



users/signals.py:



from django.db.models.signals import post_save
from django.dispatch import receiver

from conduit.apps.profiles.models import Profile

from .models import User

@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created:
instance.profile = Profile.objects.create(user=instance)


And finally an update to my users/init.py file:



from django.apps import AppConfig


class UsersAppConfig(AppConfig):
name = 'django.users'
label = 'users'
verbose_name = 'Users'

def ready(self):
import users.signals

default_app_config = 'django.users.UsersAppConfig'


That last update is something I am relatively unfamiliar with. I suspect this is where my problem is located.



I am able to resister a new user via an api call with no problem, however, when I test to see if a Profile object exists for that new user, I am left with the following error:



python manage.py shell

from users.models import CustomUser

u = CustomerUser.objects.last()

u
<CustomUser:testuser@gmail.com> --- everything works to this point

u.profile --- this is where it breaks down


I'm left with this error in shell:



users.models.CustomUser.profile.RelatedObjectDoesNotExist: CustomUser has no profile.


Any help would be appreciated, thanks!







python django django-models






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 27 '18 at 1:04









Andy GAndy G

173113




173113













  • Can you show how you create your users (i.e. how was u created in your example above)? Also, I believe your init.py file should be named __init__.py instead (two underscores before and after). This is typical Python convention...

    – Jonah Bishop
    Nov 27 '18 at 1:28













  • The init.py is not the issue. It looks like I had originally typed that, but the double underscores passed some unwanted markdown on my text. The 'u' object was created from my CustomUser model. You can see that imported during my shell session. Above that, you can see my actual CustomUser model. I left out the CustomerUserManager for the sake of brevity.

    – Andy G
    Nov 27 '18 at 1:33











  • You did call the save() routine to create your user instance though, correct? If you used something like bulk_create(), the save() routine gets bypassed, which means your signals won't fire.

    – Jonah Bishop
    Nov 27 '18 at 1:36











  • Yes, I believe so. Prior to extending the AbstractBaseUser in my CustomUser model, I defined a create_user and create_superuser function where I explicitly make a user.save() call before returning user. I'm investigating this more.

    – Andy G
    Nov 27 '18 at 1:58



















  • Can you show how you create your users (i.e. how was u created in your example above)? Also, I believe your init.py file should be named __init__.py instead (two underscores before and after). This is typical Python convention...

    – Jonah Bishop
    Nov 27 '18 at 1:28













  • The init.py is not the issue. It looks like I had originally typed that, but the double underscores passed some unwanted markdown on my text. The 'u' object was created from my CustomUser model. You can see that imported during my shell session. Above that, you can see my actual CustomUser model. I left out the CustomerUserManager for the sake of brevity.

    – Andy G
    Nov 27 '18 at 1:33











  • You did call the save() routine to create your user instance though, correct? If you used something like bulk_create(), the save() routine gets bypassed, which means your signals won't fire.

    – Jonah Bishop
    Nov 27 '18 at 1:36











  • Yes, I believe so. Prior to extending the AbstractBaseUser in my CustomUser model, I defined a create_user and create_superuser function where I explicitly make a user.save() call before returning user. I'm investigating this more.

    – Andy G
    Nov 27 '18 at 1:58

















Can you show how you create your users (i.e. how was u created in your example above)? Also, I believe your init.py file should be named __init__.py instead (two underscores before and after). This is typical Python convention...

– Jonah Bishop
Nov 27 '18 at 1:28







Can you show how you create your users (i.e. how was u created in your example above)? Also, I believe your init.py file should be named __init__.py instead (two underscores before and after). This is typical Python convention...

– Jonah Bishop
Nov 27 '18 at 1:28















The init.py is not the issue. It looks like I had originally typed that, but the double underscores passed some unwanted markdown on my text. The 'u' object was created from my CustomUser model. You can see that imported during my shell session. Above that, you can see my actual CustomUser model. I left out the CustomerUserManager for the sake of brevity.

– Andy G
Nov 27 '18 at 1:33





The init.py is not the issue. It looks like I had originally typed that, but the double underscores passed some unwanted markdown on my text. The 'u' object was created from my CustomUser model. You can see that imported during my shell session. Above that, you can see my actual CustomUser model. I left out the CustomerUserManager for the sake of brevity.

– Andy G
Nov 27 '18 at 1:33













You did call the save() routine to create your user instance though, correct? If you used something like bulk_create(), the save() routine gets bypassed, which means your signals won't fire.

– Jonah Bishop
Nov 27 '18 at 1:36





You did call the save() routine to create your user instance though, correct? If you used something like bulk_create(), the save() routine gets bypassed, which means your signals won't fire.

– Jonah Bishop
Nov 27 '18 at 1:36













Yes, I believe so. Prior to extending the AbstractBaseUser in my CustomUser model, I defined a create_user and create_superuser function where I explicitly make a user.save() call before returning user. I'm investigating this more.

– Andy G
Nov 27 '18 at 1:58





Yes, I believe so. Prior to extending the AbstractBaseUser in my CustomUser model, I defined a create_user and create_superuser function where I explicitly make a user.save() call before returning user. I'm investigating this more.

– Andy G
Nov 27 '18 at 1:58












1 Answer
1






active

oldest

votes


















0














I think your error is in your signal method:



from django.db.models.signals import post_save
from django.dispatch import receiver

from conduit.apps.profiles.models import Profile

from .models import User # you have CustomUser but you are calling User

@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created: # you should only have created because you want this happen only when it is created
instance.profile = Profile.objects.create(user=instance)


Also, I see no need updating the users init.py.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53491350%2fdjango-models-py-onetoonefield-help-creating-a-relationship-between-two-mode%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I think your error is in your signal method:



    from django.db.models.signals import post_save
    from django.dispatch import receiver

    from conduit.apps.profiles.models import Profile

    from .models import User # you have CustomUser but you are calling User

    @receiver(post_save, sender=User)
    def create_related_profile(sender, instance, created, *args, **kwargs):
    if instance and created: # you should only have created because you want this happen only when it is created
    instance.profile = Profile.objects.create(user=instance)


    Also, I see no need updating the users init.py.






    share|improve this answer




























      0














      I think your error is in your signal method:



      from django.db.models.signals import post_save
      from django.dispatch import receiver

      from conduit.apps.profiles.models import Profile

      from .models import User # you have CustomUser but you are calling User

      @receiver(post_save, sender=User)
      def create_related_profile(sender, instance, created, *args, **kwargs):
      if instance and created: # you should only have created because you want this happen only when it is created
      instance.profile = Profile.objects.create(user=instance)


      Also, I see no need updating the users init.py.






      share|improve this answer


























        0












        0








        0







        I think your error is in your signal method:



        from django.db.models.signals import post_save
        from django.dispatch import receiver

        from conduit.apps.profiles.models import Profile

        from .models import User # you have CustomUser but you are calling User

        @receiver(post_save, sender=User)
        def create_related_profile(sender, instance, created, *args, **kwargs):
        if instance and created: # you should only have created because you want this happen only when it is created
        instance.profile = Profile.objects.create(user=instance)


        Also, I see no need updating the users init.py.






        share|improve this answer













        I think your error is in your signal method:



        from django.db.models.signals import post_save
        from django.dispatch import receiver

        from conduit.apps.profiles.models import Profile

        from .models import User # you have CustomUser but you are calling User

        @receiver(post_save, sender=User)
        def create_related_profile(sender, instance, created, *args, **kwargs):
        if instance and created: # you should only have created because you want this happen only when it is created
        instance.profile = Profile.objects.create(user=instance)


        Also, I see no need updating the users init.py.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 1:47









        RarblackRarblack

        3,16641229




        3,16641229
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53491350%2fdjango-models-py-onetoonefield-help-creating-a-relationship-between-two-mode%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen