On Sun, Apr 10, 2016 at 5:12 AM, Andrew Chiw <randomshinichi4...@gmail.com> wrote:
> class Client(UserenaBaseProfile): > def __str__(self): > return self.name > > user = models.OneToOneField(User, > unique=True, > verbose_name=_('Django Login'), > related_name='client') > > name = models.CharField(max_length=100, unique=True, default=user.name > ) > > > The title says it all - this class is supposed to have a OneToOneField > relationship with a Django User, and through django-toolbar I've seen that > when a user signs up, the Django User is created first and then my Client > class. But how do I get the Client class to have the same name as the > Django User's name? > The reason this doesn't work the way you want is because Django is specifically designed not to work that way. The 'default' keyword is a database table default, not a Python code default. This means that the value for 'default' is calculated to a final value once, and when the column is created, that value is used as the 'default' and programmed directly into the database table configuration. Django does not reference this argument except during migrations (AFAIK). And, given that it is a class definition, the value is only calculated once at the start of the thread. Since it is only a class definition at run time (you are not processing an object when Django starts), your default turns out to be a OneToOne field object with no data (not a User object or anything useful), which would eventually translate into some string usable as a database default, hopefully. I ran a version of this quickly in the shell, and client.name.default ended up being None. Not sure if that is what happens during a migration, since my shell is probably running in a vacuum compared to a full makemigration run. Mike's answer about overriding the save() method and adding a helper function for your model is the way to go. It depends on the logic you want to implement, but I would expand his example a bit more to say that you first try to retrieve self.name, if that is empty then return self.user.username and/or self.user.firstname/lastname. This would assume setting a default='' on your name field. This gives you the flexibility of grabbing either the 'name' or the username if 'name' isn't available, and allowing you to build queries down the road to find all of the users that have not specified a name for themselves. With your strategy, assuming it worked, you wouldn't be able to differentiate between users with no name assigned, and those who used their usernames as their "name" intentionally. You would also need to run an extra calculation in your ORM/DB query that would compare the value of self.name and self.user.username to see if there was a difference, which is expensive and difficult to maintain. I would also suggest you add a null=True to your user field, since you likely will never have a Client object that is not associated to a User object. There is also a get_full_name() and get_short_name() on the User class that you can use, possibly instead of the "name" field you are creating. -James -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWE1PS5J4FyTvGnAKK8ha-DO2hqTERnA7R%3DPRKGC4FGfA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.