Django: how to add custom fields to data on form save?

Viewed 707

I want to insert some custom variable eg Status into the model when the user submits the form. I want the field status to be updated to Pending when a new record is inserted. This should be done automatically when the user inserts a new form. I know how to insert the form with values set by the user how can i insert my own values instead.

My current form that inserts all data into db and it looks like this

def createProcess(request):
    form = ProcessForm()
    if request.method =='POST':
        #print('Printing POST request : ', request.POST)
        form = ProcessForm(request.POST) 
        if form.is_valid():

            form.save() # above this i think i can add something to set the status
            return redirect('process_list')

    context = {'form' : form}

    return render(request, 'process/create_process.html', context)

How can I customize the value of for eg the status field? I want the status field to automatically be updated without the user submitting any information.

This is the model

class ProcessInfo(models.Model):
    process_name = models.CharField(max_length=120, null=True)
    process_L2_process_name = models.CharField(default='L2 Process Name', max_length=120, null=True)
    process_L3_process_name = models.CharField(default='L3 Process Name', max_length=120, null=True)
    process_critical = models.BooleanField(default=True, null=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    status = models.CharField(max_length=200, null=True, choices=STATUS)
    user_rel = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    tags = models.ManyToManyField(Tag)
    def __str__(self):
        return self.process_name
1 Answers

You can make a form without the status field:

class ProcessForm(forms.ModelForm):
    class Meta:
        model = Process
        exclude = ('status',)

in the view, you can then set the .status of the instance:

from django.contrib.auth.decorators import login_required

@login_required
def createProcess(request):
    form = ProcessForm()
    if request.method =='POST':
        form = ProcessForm(request.POST) 
        if form.is_valid():
            form.instance.status = 'pending'
            form.instance.user_rel = request.user
            form.save()
            return redirect('process_list')

    context = {'form' : form}
    return render(request, 'process/create_process.html', context)

You can however also specify the default value for status in your model, and set the editable=… parameter [Django-doc] to False to prevent it showing up in the form, then it is autoamtically set to default value:

class ProcessInfo(models.Model):
    # …
    status = models.CharField(
        max_length=200,
        null=True,
        choices=STATUS,
        default='pending',
        editable=False
    )

    def __str__(self):
        return self.process_name
Related