覆盖 FilterSet.qs 时无法访问 self.request.user
Can't access self.request.user when overriding FilterSet.qs
我已经编写了一个过滤器代码,该过滤器考虑了给定患者的某些字段(姓名、年龄和 ID)。该网站的用户将是医生,我希望只有当前登录医生的患者出现在搜索中。在阅读文档并尝试以多种不同方式这样做之后,我一无所获。
似乎最好的方法是重写 FilterSet.qs 函数,我也这样做了,类似于文档中的内容。但是,当我尝试访问 self.request.user 时,它返回为 none,即使当前有用户登录。
我是 Django 的新手,仍在尝试解决问题。非常感谢任何帮助。我相信我已经粘贴了所有相关的内容,但如果有遗漏,我提前表示歉意。
# filters.py
import django_filters
from .models import Patient, Teams
from django import forms
from django.contrib.auth.models import User
class PatientFilter(django_filters.FilterSet):
id = django_filters.NumberFilter(widget=forms.NumberInput(attrs={ 'min': '1'}))
age = django_filters.NumberFilter(widget=forms.NumberInput(attrs={ 'min': '0'}))
class Meta:
model = Patient
fields = {
'first_name' : ['icontains'],
'age' : ['exact'],
'id' : ['exact']
}
@property
def qs(self):
parent = super().qs
author = getattr(self.request, 'user', None)
print('Author')
print(self.request)
return parent.filter(owner=author)
# views.py
class UserPatientListView(FilterView, ListView):
model = Patient
template_name = 'bcctapp/user_patients.html'
context_object_name = 'patients'
paginate_by = 2
filterset_class = PatientFilter
def get_queryset(self):
queryset = super().get_queryset()
self.filterset = self.filterset_class(self.request.GET, queryset=queryset)
return self.filterset.qs.distinct()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = PatientFilter(self.request.GET, queryset = self.get_queryset())
context['number_results'] = context['filter'].qs.count()
return context
# models.py
class Patient(models.Model):
first_name = models.CharField(max_length=100,null=True)
last_name = models.CharField(max_length=100,null=True)
age = models.IntegerField(null=True)
birthday = models.CharField(max_length=100)
surgery_date = models.CharField(max_length=100)
patient_height = models.IntegerField(null=True)
patient_weight = models.IntegerField(null=True)
bra = models.CharField(max_length=100,null=True)
date_posted = models.DateTimeField(default=timezone.now)
owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
n_images = models.IntegerField(null=True)
team = models.IntegerField(null=True)
share = models.CharField(validators=[int_list_validator],max_length=100000, null=True)
# Surgery Type
C1 = 1
C2 = 2
C3 = 3
M1 = 4
M2 = 5
M3 = 6
M4 = 7
M5 = 8
M6 = 9
M7 = 10
SURGERY_TYPE_CHOICES = [
(C1, 'Conservative surgery - unilateral'),
(C2, 'Conservative surgery with bilateral reduction'),
(C3, 'Conservative surgery with LD or LICAP / TDAP'),
(M1, 'Mastectomy with unilateral reconstruction with implant'),
(M2, 'Mastectomy with unilateral reconstruction with autologous flap'),
(M3, 'Mastectomy with bilateral reconstruction with implants'),
(M4,
'Mastectomy with unilateral reconstruction with implant and contralateral symmetrization with implant (augmentation)'),
(M5, 'Mastectomy with unilateral reconstruction with implant and contralateral symmetrization with reduction'),
(M6,
'Mastectomy with unilateral reconstruction with autologous flap and contralateral symmetrization with reduction'),
(M7,
'Mastectomy with unilateral reconstruction with autologous flap and contralateral symmetrisation with implant (augmentation)')
]
surgery_type = models.IntegerField(choices=SURGERY_TYPE_CHOICES)
def __str__(self):
return self.first_name
def get_absolute_url(self):
return reverse('patient-detail', kwargs={'pk': self.pk})
def query_set(self,id):
return Patient(id=id)
在您的例子中,您正在尝试使用登录用户过滤基本查询集。为此,您不需要 过滤器集 class,只需覆盖 get_queryset(...)
方法
class UserPatientListView(FilterView, ListView):
model = Patient
template_name = 'bcctapp/user_patients.html'
context_object_name = 'patients'
paginate_by = 2
filterset_class = PatientFilter
<b>def get_queryset(self):
queryset = super().get_queryset().filter(owner=self.request.user)
return queryset</b>
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = PatientFilter(self.request.GET, queryset=self.get_queryset())
context['number_results'] = context['filter'].qs.count()
return context
我已经编写了一个过滤器代码,该过滤器考虑了给定患者的某些字段(姓名、年龄和 ID)。该网站的用户将是医生,我希望只有当前登录医生的患者出现在搜索中。在阅读文档并尝试以多种不同方式这样做之后,我一无所获。
似乎最好的方法是重写 FilterSet.qs 函数,我也这样做了,类似于文档中的内容。但是,当我尝试访问 self.request.user 时,它返回为 none,即使当前有用户登录。
我是 Django 的新手,仍在尝试解决问题。非常感谢任何帮助。我相信我已经粘贴了所有相关的内容,但如果有遗漏,我提前表示歉意。
# filters.py
import django_filters
from .models import Patient, Teams
from django import forms
from django.contrib.auth.models import User
class PatientFilter(django_filters.FilterSet):
id = django_filters.NumberFilter(widget=forms.NumberInput(attrs={ 'min': '1'}))
age = django_filters.NumberFilter(widget=forms.NumberInput(attrs={ 'min': '0'}))
class Meta:
model = Patient
fields = {
'first_name' : ['icontains'],
'age' : ['exact'],
'id' : ['exact']
}
@property
def qs(self):
parent = super().qs
author = getattr(self.request, 'user', None)
print('Author')
print(self.request)
return parent.filter(owner=author)
# views.py
class UserPatientListView(FilterView, ListView):
model = Patient
template_name = 'bcctapp/user_patients.html'
context_object_name = 'patients'
paginate_by = 2
filterset_class = PatientFilter
def get_queryset(self):
queryset = super().get_queryset()
self.filterset = self.filterset_class(self.request.GET, queryset=queryset)
return self.filterset.qs.distinct()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = PatientFilter(self.request.GET, queryset = self.get_queryset())
context['number_results'] = context['filter'].qs.count()
return context
# models.py
class Patient(models.Model):
first_name = models.CharField(max_length=100,null=True)
last_name = models.CharField(max_length=100,null=True)
age = models.IntegerField(null=True)
birthday = models.CharField(max_length=100)
surgery_date = models.CharField(max_length=100)
patient_height = models.IntegerField(null=True)
patient_weight = models.IntegerField(null=True)
bra = models.CharField(max_length=100,null=True)
date_posted = models.DateTimeField(default=timezone.now)
owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
n_images = models.IntegerField(null=True)
team = models.IntegerField(null=True)
share = models.CharField(validators=[int_list_validator],max_length=100000, null=True)
# Surgery Type
C1 = 1
C2 = 2
C3 = 3
M1 = 4
M2 = 5
M3 = 6
M4 = 7
M5 = 8
M6 = 9
M7 = 10
SURGERY_TYPE_CHOICES = [
(C1, 'Conservative surgery - unilateral'),
(C2, 'Conservative surgery with bilateral reduction'),
(C3, 'Conservative surgery with LD or LICAP / TDAP'),
(M1, 'Mastectomy with unilateral reconstruction with implant'),
(M2, 'Mastectomy with unilateral reconstruction with autologous flap'),
(M3, 'Mastectomy with bilateral reconstruction with implants'),
(M4,
'Mastectomy with unilateral reconstruction with implant and contralateral symmetrization with implant (augmentation)'),
(M5, 'Mastectomy with unilateral reconstruction with implant and contralateral symmetrization with reduction'),
(M6,
'Mastectomy with unilateral reconstruction with autologous flap and contralateral symmetrization with reduction'),
(M7,
'Mastectomy with unilateral reconstruction with autologous flap and contralateral symmetrisation with implant (augmentation)')
]
surgery_type = models.IntegerField(choices=SURGERY_TYPE_CHOICES)
def __str__(self):
return self.first_name
def get_absolute_url(self):
return reverse('patient-detail', kwargs={'pk': self.pk})
def query_set(self,id):
return Patient(id=id)
在您的例子中,您正在尝试使用登录用户过滤基本查询集。为此,您不需要 过滤器集 class,只需覆盖 get_queryset(...)
方法
class UserPatientListView(FilterView, ListView):
model = Patient
template_name = 'bcctapp/user_patients.html'
context_object_name = 'patients'
paginate_by = 2
filterset_class = PatientFilter
<b>def get_queryset(self):
queryset = super().get_queryset().filter(owner=self.request.user)
return queryset</b>
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = PatientFilter(self.request.GET, queryset=self.get_queryset())
context['number_results'] = context['filter'].qs.count()
return context