1

views.py

from django.shortcuts import render
from basic_app.forms import UserForm,UserProfileInfoForm



# Extra Imports for the Login and Logout Capabilities
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.contrib.auth.decorators import login_required

# Create your views here.
def index(request):
    return render(request,'basic_app/index.html')

@login_required
def special(request):
    # Remember to also set login url in settings.py!
    # LOGIN_URL = '/basic_app/user_login/'
    return HttpResponse("You are logged in. Nice!")

@login_required
def user_logout(request):
    # Log out the user.
    logout(request)
    # Return to homepage.
    return HttpResponseRedirect(reverse('index'))

def register(request):

    registered = False

    if request.method == 'POST':

        # Get info from "both" forms
        # It appears as one form to the user on the .html page
        user_form = UserForm(data=request.POST)
        profile_form = UserProfileInfoForm(data=request.POST)

        # Check to see both forms are valid
        if user_form.is_valid() and profile_form.is_valid():

            # Save User Form to Database
            user = user_form.save()

            # Hash the password
            user.set_password(user.password)

            # Update with Hashed password
            user.save()

            # Now we deal with the extra info!

            # Can't commit yet because we still need to manipulate
            profile = profile_form.save(commit=False)

            # Set One to One relationship between
            # UserForm and UserProfileInfoForm
            profile.user = user

            # Check if they provided a profile picture
            if 'profile_pic' in request.FILES:
                print('found it')
                # If yes, then grab it from the POST form reply
                profile.profile_pic = request.FILES['profile_pic']

            # Now save model
            profile.save()

            # Registration Successful!
            registered = True

        else:
            # One of the forms was invalid if this else gets called.
            print(user_form.errors,profile_form.errors)

    else:
        # Was not an HTTP post so we just render the forms as blank.
        user_form = UserForm()
        profile_form = UserProfileInfoForm()

    # This is the render and context dictionary to feed
    # back to the registration.html file page.
    return render(request,'basic_app/registration.html',
                          {'user_form':user_form,
                           'profile_form':profile_form,
                           'registered':registered})

forms.py

-

from django import forms
from django.contrib.auth.models import User
from basic_app.models import UserProfileInfo

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta():
        model = User
        fields = ('username','email','password')


class UserProfileInfoForm(forms.ModelForm):
    class Meta():
        model = UserProfileInfo
        fields = ('portfolio_site','profile_pic')

And, here is another file that I found on Internet. This code is separate from the above code

forms.py ---- different

@login_required
def edit_profile(request):
    ''' edit profile view for the accounts application '''
    user = get_object_or_404(User, username=request.user)
    form = EditProfileForm(instance=user)

    print('Files : {}'.format(request.FILES)) 
    if request.method == 'POST':

        form = EditProfileForm(instance=user,
                               data=request.POST,
                               files=request.FILES
                              )

I don't understand what the how the arguments can be passed into the forms that I defined. For example, I don't understand these lines of code:

    user_form = UserForm(data=request.POST)
    profile_form = UserProfileInfoForm(data=request.POST)

Where is the argument data defined? In the same way, in these lines of code:

form = EditProfileForm(instance=user,
                       data=request.POST,
                       files=request.FILES
                      )

where were the arguments, instance, data, files, defined?

I think I'm lacking understanding of how the user request works in conjunction with forms.

1
  • 1
    It is subclassed from a ModelForm. Commented Jun 3, 2018 at 10:04

1 Answer 1

2

The forms you provide are subclasses of ModelForm:

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta():
        model = User
        fields = ('username','email','password')

A ModelForm (and its superclasses) are a set of classes that implement some binding between the model instance and a Form. For example it will make sure that if an instance is provided, then the form elements are filled with that data. On the other hand if you provide data, it can construct a new model instance, etc.

If we for example inspect the source code we see:

class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass):
    pass

So basically ModelForm inherits all from BaseModelForm, and there is a metaclass involved that will basically check if there is a Meta class in your Form (here there is), and perform some actions on it.

Regardless what the metaclass does, we see that the __init__ of BaseModelForm is defined as [src]:

class BaseModelForm(BaseForm):
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=None,
                 empty_permitted=False, instance=None, use_required_attribute=None):
        # ...
        pass

Since we inherit the __init__ function, all the arguments like data, files, auto_id, etc. are inherited as well.

Sign up to request clarification or add additional context in comments.

2 Comments

wow. Your explanation does make sense, but I'm just a novice and this feels really overwhelming to me.... I don't really know what each of those parameters are...
Well typically the most important are instance to provide an instance you want to update, data to pass request.POST that contains the data of the form (for example to save this into the instance). But typically the Django manual(s) will explain the parameters in a by need case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.