Jimmy
Jimmy

Reputation: 63

Django how to save value to model without being present on form post

I have the following Model/form/view:

Model

class Account(models.Model):
    username = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    name = models.CharField(max_length=150)
    identifier_type = models.ForeignKey(IdentifierType, on_delete=models.SET_NULL, null=True)
    actflag = models.CharField(max_length=1, blank=True)
    created_date = models.DateTimeField(blank=True, null=True)
    comments = models.TextField(_(
        'comments'), max_length=500, blank=True)
    priority_type = models.ForeignKey(PriorityType, on_delete=models.SET_NULL, null=True)
    deadline_date = models.DateTimeField(blank=True, null=True)


    def __str__(self):
        return self.name

Form

class PortfolioForm(forms.ModelForm):
    portfolio = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = Account
        fields = ['name', 'comments', 'priority_type', 'deadline_date', 'identifier_type', 'portfolio']

View

def portfolios(request):

    if request.user.is_authenticated:

        if request.POST:
            fm = PortfolioForm(request.POST)

            user = User.objects.get(username=request.user)

            if fm.is_valid():
                messages.success(request, 'Portfolio has been created.')                

                fm.save()

                return redirect('portfolios')
        else:
            fm = PortfolioForm()

        context = {"name": request.user, "form": fm}

        return render(request, 'portfolios.html', context)

    else:
        return redirect('login')

The form works fine with posting via my template, however you will notice there are some fields within my model that are not in my form I would like to fill in automatically without the user having to fill in - for example username field I would like this to be current user that submits the form and also created_date would like the current date time the user has submitted the form.

I tried to add the following to my view under if fm.is_valid(): attempting to save username as current user to the model but did not work:

                Account.objects.username = request.user

How can I go about doing this? Thanks in advance

Upvotes: 1

Views: 821

Answers (2)

boyenec
boyenec

Reputation: 1637

You can use django forms instance for saving any predefined value without showing or render those fields to your users or html template. Here is an example how to automatically save your username and created_date fields .

if fm.is_valid():               
                fm = fm.save(commit=False)
                fm.instance.username = request.user  
                fm.instance.created_date = timezone.now()
                fm.save()

Upvotes: 1

Tonio
Tonio

Reputation: 1782

You can save these values after creating the Account object when you save the form. If you use the commit=False parameter in the save method, this does not hit the database and you can easy modify the Account object.

from django.utils import timezone


def portfolios(request):
    if request.user.is_authenticated:
        if request.POST:
            fm = PortfolioForm(request.POST)
            # user = User.objects.get(username=request.user)

            if fm.is_valid():               
                account = fm.save(commit=False)
                account.username = request.user 
                account.created_date = timezone.now()
                account.save()

                messages.success(request, 'Portfolio has been created.') 
                return redirect('portfolios')
        else:
            fm = PortfolioForm()

        context = {"name": request.user, "form": fm}
        return render(request, 'portfolios.html', context)

    else:
        return redirect('login')

Upvotes: 1

Related Questions