Save customer in the background on django forms

Question:

Hi I am trying to automatically save the customer on post without having to list it in the forms. It currently shows the drop down and saves correctly but if I remove customer from forms.py it doesn’t save anymore.
views.py

  @login_required(login_url='login')
  def createInfringer(request):

     customer=request.user.customer

     form = InfringerForm(customer=customer)
     if request.method == 'POST':
  
        form = InfringerForm(customer, request.POST)
        if form.is_valid():
     
        form.save()
     return redirect('infringer-list')
  context ={'form': form}
  return render (request, 'base/infringement_form.html', context)

forms.py

   class InfringerForm(ModelForm):
   def __init__(self, customer, *args, **kwargs):
   super(InfringerForm,self).__init__(*args, **kwargs)
   self.fields['customer'].queryset = Customer.objects.filter(name=customer)
   self.fields['status'].queryset = Status.objects.filter(customer=customer)
   class Meta:
    model = Infringer
    fields = ['name', 'brand_name','status','customer']

UPDATE
suggestion below was added but it still doesn’t save customer.

Asked By: Farid

||

Answers:

If I am understanding your problem correctly, you’d like to save the customer in your model but do not wish to show the customer field on your form as the customer is the logged-in user. If that assumption is correct, you need to first remove the customer field from your form fields and its __init__ method. Then, you’d need to pass the customer to your save method during the post request as your model probably requires that field:

@login_required(login_url='login')
def createInfringer(request):
    customer=request.user.customer
    form = InfringerForm(customer=customer)
    if request.method == 'POST':
        form = InfringerForm(customer, request.POST)
        if form.is_valid():   
            saved_instance = form.save(customer)
            print (f'Successfully saved the infringer with its customer {saved_instance.customer}')  ## Insert this and see what it says

        return redirect('infringer-list')
    
    context ={'form': form}
    return render (request, 'base/infringement_form.html', context)

class InfringerForm(ModelForm):
    class Meta:
       model = Infringer
       # fields = ['name', 'brand_name','status','customer']
       fields = ['name', 'brand_name','status']  # Notice the above commented line. Also, Add this instead
    
    def __init__(self, customer, *args, **kwargs):
        super(InfringerForm,self).__init__(*args, **kwargs)
        # self.fields['customer'].queryset = Customer.objects.filter(name=customer)
        self.fields['status'].queryset = Status.objects.filter(customer=customer)
    
    def save(self, customer, *args, **kwargs):
        instance = super(InfringerForm, self).save( *args, **kwargs) 
        if customer:
            print (f'customer is {customer}')
            self.customer = customer
        
        instance.save()
        print (f'instance was saved with the customer {instance.customer}')
        return instance
        

I have not tested the above code, but it should work

Answered By: EarlyCoder

forms.py

class InfringerForm(ModelForm):    
 class Meta:
   model = Infringer
   fields = ['name', 'brand_name', 'status']  

  def __init__(self, customer, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.customer = customer
    self.fields['status'].queryset = Status.objects.filter(customer=customer)

  def save(self, *args, **kwargs):
    self.instance.customer = self.customer
    return super().save( *args, **kwargs)

views.py

@login_required(login_url='login') def createInfringer(request):
customer = request.user.customer
form = InfringerForm(customer=customer)
if request.method == 'POST':
    form = InfringerForm(customer, request.POST, request.FILES)
    if form.is_valid():   
        saved_instance = form.save()
        print (f'customer in views.py is {customer}')
        print (f'Successfully saved the infringer in views.py with its customer {saved_instance.customer}')
        return redirect('infringer-list')

return render (request, 'base/infringement_form.html', {'form': form})
Answered By: Farid
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.