4

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

2 Answers 2

3

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().

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

2 Comments

Thank You Abdul Aziz Barkat you are a lifesaver, highly appreciated.
@MuhammadSharif also I noticed that you use that try-except to prevent those integrity errors? Perhaps this question might be helpful to you, it is on making the form itself validate the unique constraints.
3

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)

Comments

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.