In Django create a model method which determines an id for all objects that share the same foreign key

Kind of new to Django and while trying to create my first own project, i stumbled upon a problem. I have two different model classes: Star and Planet. Each planet has a foreignkey which belongs to a Star. Now I would like to have a field for Planet, which is basically the id/pk for its star system that is given on creation/discovery. All known planets of the star system already have their star system id and thus the newly created/discovered planet would require an id that is incremented on the last id that was given.

Id Star Id in Star System Name
1 Sun 1 Neptune
2 Alpha Centauri 1 Hoth
3 Alpha Centauri 2 Coruscant
4 Sun 2 Earth
5 Sun 3 Jupiter
6 Alpha Centauri 3 Yavin4
7 Sun 4 Venus

My models are looking like this

models.py:

class Star(models.Model):
   name = models.CharField(max_length=200)

class Planet(models.Model):
   name = models.CharField(max_length=200)
   star = models.ForeignKey(Star, on_delete=models.CASCADE)

   def starSystemPlanetId(self):
      What could work in here?

This new Id should be available to be called in a template like this:

{% for planets in object_list %}
    <li> 
         <p>Planet {{planets.name}} is the Nr. {{planets.customer_id}} planet of the star system</p>
    </li>
{% endfor %}

I have learned already, that business logic should be implemented inside models.py via a model method.

def starSystemPlanetId(self, star_var):
   starSystemPlanetId = Planet.objects.filter(star = star_var).filter(pk >> earlierPlanetsPk).count()
   return starSystemPlanetId

Maybe there is a standard query function available for this kind of problem already.

Any help and thought about it is very welcome!

This is my suggestion (following the comments on you post):

class Planet(models.Model):
    name = models.CharField(max_length=200)
    star = models.ForeignKey(Star, on_delete=models.CASCADE, related_name='planets')

    # Use property since it's more pythonic
    @property
    def star_system_planet_id(self):
       """0-based display identifier for a planet in the start system."""
        # No need for the 'star_var' variable since you already have it in the 
        # model instance
        return self.star.planets.filter(pk__lt=self.pk).count()

Small note: the property won't work for objects that have not been stored in the DB cause they don't have the PK assigned yet. For this, you probably want to return an empty string or None, etc. Up to you.

Back to Top