'django form queryset filter using request user

I want to filter queryset using current user data but it's return only a Nonetype Suppose When I remove None its shows the error user can't recognize

In Forms.py

class oldenquiryForm(forms.ModelForm):
    class Meta:
        model=enquiry
        fields=['product','type','created_at']
        widgets={
            'created_at':forms.DateInput(attrs={'type':'date'}),
        }
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        user = kwargs.pop('user', None)
        super(oldenquiryForm, self).__init__(*args, **kwargs)
        employee = emp.objects.filter(branch=user.admin.branch_name).values_list('firstname',flat=True)
        print (employee)
        self.fields['created_by'].queryset=emp.objects.filter(branch=user.admin.branch_name).values_list('firstname',flat=True)

views.py

I want to get the emp data is similar to admin branch

def enquirys(request):
    if request.method=='POST':
        form=oldenquiryForm(request.POST)
        if form.is_valid():
            form.save()
    else:
         return render(request,'enquirys.html',{'form':form})

models.py

I have linked the admin,emp to user model

class admin(models.Model):
user=models.OneToOneField(User,null=True,on_delete=models.CASCADE)
firstname=models.CharField(default='',max_length=100,null=False)
created_by=models.CharField(default='',max_length=100)
phonenumber=models.TextField(default='',null=False,unique=True)
photo=models.ImageField(upload_to='admin_photo/',default='user.jpg')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(default=timezone.now)
branch= models.ForeignKey(branch,null=True,on_delete=models.CASCADE)
branch_name= models.CharField(default='',max_length=100)
def __str__(self):
 return self.firstname

class emp(models.Model):
    user=models.OneToOneField(User,null=True,on_delete=models.CASCADE)
    firstname=models.CharField(default='',max_length=100,null=False)
    lastname=models.CharField(default='',max_length=100,null=False)
    gender=(
        ('M','Male'),
        ('F','Female'),
        ('O','Others'),
        )
    gender=models.CharField(choices=gender, default='',max_length=10)
    dob=models.DateField(default=datetime.now)
    created_by=models.CharField(default='',max_length=100)
    phonenumber=models.TextField(default='',null=False,unique=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(default=timezone.now)
    branch=models.CharField(default='',max_length=100)


Solution 1:[1]

You should call the super constructor without the user field, so removing it from the named parameters before, for example by adding user=None to the signature:

class OldEnquiryForm(forms.ModelForm):
    def __init__(self,*args, user=None, **kwargs):
        super(oldenquiryForm, self).__init__(*args, **kwargs)
        if user is not None:
            self.fields['created_by'].queryset = emp.objects.filter(branch=user.admin.branch_name)

    class Meta:
        model=enquiry
        fields=['product','type','created_at']
        widgets={
            'created_at':forms.DateInput(attrs={'type':'date'}),
        }

Then in the view, you construct the form with the logged in user as user:

from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect

@login_required
def enquirys(request):
    if request.method == 'POST':
        form = OldEnquiryForm(request.POST, request.FILES, user=request.user)
        if form.is_valid():
            form.save()
            return redirect('name-of-some-view')
    else:
        form = OldEnquiryForm(user=request.user)
    return render(request,'enquirys.html',{'form':form})

Probably you should also construct a model for the branch and use a ForeignKey to implement database normalization [wiki].


Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].


Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Willem Van Onsem