Cannot understand how this property on a model is being invoked
<p>I am going over a tutorial on extending a user model and it seems to work however I had 2 questions on how a property is being invoked and about a constructor. First this is the code in question</p>

<p>The main model is this</p>

<pre><code>class UserProfile(models.Model):
    user = models.OneToOneField(User)
    likes_cheese = models.BooleanField(default=True)
    puppy_name = models.CharField(max_length=20)

User.profile = property(lambda u : UserProfile.objects.get_or_create(user=u)[0])---&gt;Statement A
</code></pre>

<p>Now the form which gets presented to the user is this</p>

<pre><code>class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('likes_cheese','puppy_name')
</code></pre>

<p>and the view that presents this form is as follows this is where my questions are (Over here i am simply interested in presenting the form so I removed the other code out):</p>

<pre><code>def user_profile(request):
    display_page = "profile.html"
    csrf_token = csrf(request)
    args={}
    user  = request.user
    profile = user.profile    ----------------------&gt;statement B - Question 1 below
    form = UserProfileForm(instance=profile) -------&gt;statement C - Question 2 below
    args.update(csrf_token)
    args["form"] = form
    return render_to_response(display_page,args)
</code></pre>

<p>Now here are my two questions </p>

<p>Q1- Why isnt a parameter being passed to the property <code>profile</code> of <code>User</code> object ?</p>

<p>from what I understand from statement A which is </p>

<pre><code>  User.profile = property(lambda u : UserProfile.objects.get_or_create(user=u)[0])
</code></pre>

<p>is that profile is being defined as a property of User and that it has a setter function which is a lambda that takes a parameter. Where is that parameter being passed ? All i see is this (A parameter to the property is not being passed anywhere that I can see)</p>

<pre><code>        profile = user.profile   
        form = UserProfileForm(instance=profile)
</code></pre>

<p>Q2-In the code <code>form = UserProfileForm(instance=profile)</code> we are passing in an instance as a parameter but my UserProfileForm does not have a constructor ? What is happening here.</p>

<p>Thanks in advance</p>

<p><strong>Q1</strong>: Because you are using django predefined <code>User</code> class you have two options to add new property(to inherit <code>User</code> model and say django to use it for just adding new property), or just do it like you did.</p>

<p>When you call <code>user.profile</code> you already passing <code>user</code> as a parameter, so that <code>lambda</code> does <code>UserProfile.objects.get_or_create(user=user)[0]</code></p>

<p><strong>Q2</strong>: Your <code>UserProfileForm</code> inherit from <code>forms.ModelForm</code> which already has a constructor. And you can pass <code>instance</code> argument, so that form would be populated with model data(<code>UserProfile</code>).</p>

<p><code>django.forms.ModelForm</code> at the same moment inherit from <code>django.forms.models.BaseModelForm</code> and in <code>__init__</code> it checks if <code>instance</code> keyword argument is provided and populates form as follows, from <a href="https://docs.djangoproject.com/en/1.10/_modules/django/forms/models/#ModelForm" rel="nofollow">source</a></p>

<pre><code>if instance is None:
    # if we didn't get an instance, instantiate a new one
    self.instance = opts.model()
    object_data = {}
</code></pre>

python django django-models lambda django-forms