Best way to create Django instances while manipulating/hiding fields from caller?
<p>Suppose I have the following Django class:</p>

<pre><code>from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=254)
    year_of_birth = models.IntegerField()
</code></pre>

<p>I can create an instance of the model by doing the following:</p>

<pre><code>p = Person.object.create(name="Mahmoud", year_of_birth=1985)
</code></pre>

<p>However, I don't want the calling function outside the <code>Person</code> class to know the internal details of the class. And I also don't want them to have to calculate their year of birth. I just want them to enter their age (21), and I want to write a method that takes care of the rest for them automatically. </p>

<p>This is a common need I have throughout my Django application. Is there a preferred pattern to solve this problem? Currently, I'm doing it by creating the following static method in the <code>Person</code> class:</p>

<pre><code>import datetime

@staticmethod
def create(name, age):
    return Person.objects.create(name=name, year_of_birth=datetime.datetime.now().year-age)
</code></pre>

<p>And then I call it like this: <code>p = Person.create(name="Mahmoud", age=21)</code></p>

<p>But I'm not sure this is the best way to go. Is this the proper/pythonic way to handle this situation?</p>

<p>Maybe you can add a Person manager to your Person model class like this:</p>

<pre><code>objects = PersonManager()
</code></pre>

<p>Then define a method inside PersonManager() that creates a person:</p>

<pre><code>class PersonManager(models.Manager):
    def create_person(name, age):
        return self.create(name=name, year_of_birth=datetime.datetime.now().year-age)
</code></pre>

<p>And you'd use it like this:</p>

<pre><code>person = Person.objects.create_person("Dude", 23)
</code></pre>

python django django-models