'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_requireddecorator [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 |
