1

models.py, it doesn't work. I've tried everything.

class UserProfile(models.Model):
        user = models.OneToOneField(User)
        titulo = models.CharField(max_length=50, default= user.get_username())
        descripcion = models.TextField()

Error waking up the server "OneToOneField doesn't have attribute get_username". I wanna set default profile page title for users using their own username.

1 Answers1

3

Specifying a dynamic default on class declaration time can not work, because Python is only analyzing this code once your app starts and not when an actual instance is saved.

Instead override your model's save() method to check if titulo is empty. If it is then you can set it to user.get_username() like this:

# models.py
class UserProfile(models.Model):
    user = models.OneToOneField(User)
    titulo = models.CharField(max_length=50, blank=True, default="")
    descripcion = models.TextField()

    def save(self, *args, **kwargs):
        # If titulo is empty set it to the username.
        if not self.titulo:
            self.titulo = self.user.get_username()

        # Now call the save() method on super to store the instance.
        super(UserProfile, self).save(*args, **kwargs)

Another question is if you really want to save the username into titulo. That way, if a user changes her username, you have to track that and synchronize the field, which adds even more housekeeping logic into your code.

It might be easier and less error-prone to allow titulo to be blank and in your views or templates check if it is. If yes, you can still render user.get_username(), if not you can render titulo.

sthzg
  • 5,514
  • 2
  • 29
  • 50
  • Thanks, that's what I need. I can copy&paste, but, ... I wanna know what *args, **kwargs are? –  Jun 05 '15 at 16:58
  • They are placeholders for arbitrary positional and keyword arguments and widely used in Python. See http://stackoverflow.com/a/3394898/870769 for a good explanation. – sthzg Jun 05 '15 at 17:02
  • It is even better if you use a `post_save` [signal](https://docs.djangoproject.com/en/1.8/topics/signals/). Good answer. – Gocht Jun 05 '15 at 20:36
  • @Gocht if you want to modify data it should rather be `pre_save`. In general signals should be used as rarely as possible and make sense when you have to listen to events from other models to keep the code decoupled. That's not really necessary here, since `UserProfile` is directly controlled by the OP and the data to be modified is on that very same model instance. Also, there is the big caveat that the pre and post signals don't get triggered on [bulk operations](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#bulk-create) – sthzg Jun 05 '15 at 20:59
  • @sthzg you are right, in this case should be a `pre_save`, personally I think is more readable using signals. About bulk operations, one again you are right, that's why I linked to docs. – Gocht Jun 05 '15 at 21:09