1

Objective: I am trying to set the __str__ of a model to the name of a related model. The Profile model has a __str__ that returns "last name, first name" of the user. I would like the Inspector to return something similar with their inspector_number.

Currently: The __str__ is returning "users.Profile.None 12345" instead of the desired "Doe, John 12345".

This is one of my first times using related_name for a model and I seem to be missing something.

Model.py

class Profile(BaseModel):
    user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True, blank=True)
    inspector = models.ForeignKey(Inspector, on_delete=models.SET_NULL, null=True, blank=True, related_name="inspector_profile")
    
    def __str__(self):
        return self.user.last_name + ", " + self.user.first_name



class Inspector(BaseModel):

...

    inspector_number = models.CharField(max_length=19, unique=True, editable=False, default=get_inspector_number)


    def __str__(self):
        ret = str(self.inspector_profile) + " " + str(self.inspector_number)
        return ret

Update: I was able to solve the issue by using if hasattr(self, 'inspector_profile'):. All of the records had the attribute but this seemed to correct my issue.

Aiden
  • 309
  • 2
  • 16
  • It looks like there is no Profile related to your Inspector instance. Are you sure the data is correct? You should probably check if the inspector has this relation since it is nullable – vinkomlacic Mar 09 '22 at 19:54
  • @vinkomlacic Agreed, that is exactly what it looks like but if I go into the Profile then I can see the Inspector is assigned. If I remove the Inspector from the Profile then it still shows the same information/result. – Aiden Mar 09 '22 at 21:04
  • I guess it's something related to model design. You could make the `__str__` of the Profile to print the desired string. For example, `return self.user.last_name + ", " + self.user.first_name + inspector.inspector_number`. – Gejun Mar 09 '22 at 21:12

1 Answers1

1

The reason this happens is because inspector is a ForeignKey. This means that an Inspector can have zero, one, or more related Profiles, and this also means that self.inspector_profile is not a Profile object, but a RelatedObjectManager that manages Profile objects. You can for example print all the related Profile names with:

class Inspector(BaseModel):
    # …
    
    def __str__(self):
        profiles = [str(profile) for profile in self.inspector_profile.all()]
        return f'{" ".join(profiles)} {self.inspector_number}'

But probably the main question is if an Inspector should be related to potentially multiple Profiles, and that the relation should not be a OneToOneField from Inspector to Profile.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555