Muhammad Sharif
Muhammad Sharif

Reputation: 466

Django form.save(commit=False) not adding user_id

I am trying to add created by whoever is logged in user but not getting that saved even though I am logged in. form.created_by = request.user is not adding logged in user.

def create_table_allotment(request):
    form = TableAllotmentForm(request.POST or None)
    context = {'form': form}

    if request.method == 'POST':
        if form.is_valid():
            try:
                form.save(commit=False)
                form.created_by = request.user
                form.save()
                return redirect('order_management:table_allotment_home')
            except IntegrityError as err:
                print('err => ', err)
                context['unique_error'] = 'User has already assigned table for today'

    return render(request, 'orders/table_allotment/create.html', context)

Here are my models

class QOTs(models.Model):
    name = models.CharField(max_length=50)
    alias = models.CharField(max_length=10)

    def __str__(self):
        return str(self.name)

    class Meta:
        verbose_name_plural = "QOTs"


class TableAllotment(models.Model):
    employee = models.ForeignKey(User, on_delete=models.PROTECT)
    qot = models.ForeignKey(QOTs, on_delete=models.PROTECT)
    club = models.CharField(max_length=20, default='POS-0001')
    from_table = models.IntegerField()
    to_table = models.IntegerField()
    working_date = models.DateField(default=timezone.now)

    created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='qot_creator')
    created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(_("Updated at"), auto_now=True)

    class Meta:
        ordering = ('-id',)
        unique_together = ('employee', 'working_date',)

Here is my form

class TableAllotmentForm(forms.ModelForm):
    class Meta:
        model = models.TableAllotment
        fields = ["employee", "qot", "from_table", "to_table"]

Please help

Upvotes: 4

Views: 1970

Answers (2)

NKSM
NKSM

Reputation: 5854

An alternative approach to what Abdul Aziz Barkat has suggested would be to assign returned object of save()(Django-Docs) method like so obj = form.save(commit=False).

I would also add @login_required to the view

from django.contrib.auth.decorators import login_required

@login_required
def create_table_allotment(request):
    if request.method == 'POST':
        form = TableAllotmentForm(request.POST)
        if form.is_valid():
            try:
                obj = form.save(commit=False)
                obj.created_by = request.user
                obj.save()
                return redirect('order_management:table_allotment_home')
            except IntegrityError as err:
                print('err => ', err)
                context['unique_error'] = 'User has already assigned table for today'
    else:
        form = TableAllotmentForm()

    context = {'form': form}
    return render(request, 'orders/table_allotment/create.html', context)

Upvotes: 3

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21787

form.save(commit=False) will return the instance wrapped by the form which you can then modify and call save on. Instead you are just calling save on the form again and also you are setting form.created_by = request.user i.e. you are setting an attribute on the form.

Instead you should directly modify the instance wrapped by the form:

def create_table_allotment(request):
    form = TableAllotmentForm(request.POST or None)
    context = {'form': form}

    if request.method == 'POST':
        if form.is_valid():
            try:
                form.instance.created_by = request.user
                form.save()
                return redirect('order_management:table_allotment_home')
            except IntegrityError as err:
                print('err => ', err)
                context['unique_error'] = 'User has already assigned table for today'

    return render(request, 'orders/table_allotment/create.html', context)

Note: TableAllotmentForm(request.POST or None) is an anti-pattern (It is possible for an empty form to be valid in certain conditions) and you should simply pass request.POST only if request.method == "POST" else you should simply write TableAllotmentForm().

Upvotes: 3

Related Questions