如何根据 Django 中另一个模型的值过滤查询集?
How to filter queryset based on value of another model in Django?
我正在尝试制作一个简单的搜索功能。我正在使用 User
模型和具有 OneToOne 关系的 UserProfile
模型。我已经成功地通过用户名、名字和姓氏进行搜索,所有三个字段都在 User
模型中。但是,我想按 UserProfile
模型中存在的字段进行过滤,例如性别、年龄、地点等
views.py
def Home(request):
query = request.GET.get('query', '')
queryset = User.objects.none()
if request.method == "GET":
form = SearchForm(request.GET)
if form.is_valid():
if query != '':
queryset = User.objects.filter(Q(username__icontains=query)
| Q(first_name__icontains=query)
| Q(last_name__icontains=query)).exclude(is_staff=True)
else:
form = SearchForm()
return render(request, "main/home.html", {'form': form, 'queryset': queryset})
home.html
{% extends "base.html" %}
{% block body %}
<h3>Home</h3>
<p>
<form method="get" action="">
{{ form.as_p }}
<input type="submit" value="Search"/>
</form>
</p>
<p>
{% for user in queryset %}
<a href="{% url 'main:profile' user.id %}">{{ user.get_full_name }}</a> <br/>
{% endfor %}
</p>
{% endblock %}
forms.py
class SearchForm(forms.Form):
query = forms.CharField(max_length=100, label="", widget=forms.TextInput(attrs={'placeholder': 'Search...'}), required=False)
age_from = forms.IntegerField(label="", widget=forms.NumberInput(attrs={'placeholder': 'Age from'}), required=False)
age_to = forms.IntegerField(label="", widget=forms.NumberInput(attrs={'placeholder': 'Age to'}), required=False)
models.py
UserProfile(models.Model):
sex_choices = (
('Male', 'Male'),
('Female', 'Female'),
('Other', 'Other'),
)
sex = models.CharField(max_length=6,
choices=sex_choices,
default='Male')
birth_date = models.DateField()
如何在与 User
模型具有一对一关系的 UserProfile
模型上添加基于其他字段的搜索选项?
您需要使用相关名称。
由于您尚未共享模型定义,我们假设:
class UserProfile(models.Model):
user = models.OneToOneField(User)
sex = models.CharField(...)
...
因此,当您查询时:
User.objects.filter(user_profile_set__sex='female')
编辑
要根据年龄进行查询,假设您在表单中要求 'age' 并在模型中存储生日,您可以尝试这样的操作:
from datetime import datetime
age = 18 # this shoudl come from form
birth_year = datetime.now().year - age
User.objects.filter(user_profile_set__birth_date__year=birth_year)
我正在尝试制作一个简单的搜索功能。我正在使用 User
模型和具有 OneToOne 关系的 UserProfile
模型。我已经成功地通过用户名、名字和姓氏进行搜索,所有三个字段都在 User
模型中。但是,我想按 UserProfile
模型中存在的字段进行过滤,例如性别、年龄、地点等
views.py
def Home(request):
query = request.GET.get('query', '')
queryset = User.objects.none()
if request.method == "GET":
form = SearchForm(request.GET)
if form.is_valid():
if query != '':
queryset = User.objects.filter(Q(username__icontains=query)
| Q(first_name__icontains=query)
| Q(last_name__icontains=query)).exclude(is_staff=True)
else:
form = SearchForm()
return render(request, "main/home.html", {'form': form, 'queryset': queryset})
home.html
{% extends "base.html" %}
{% block body %}
<h3>Home</h3>
<p>
<form method="get" action="">
{{ form.as_p }}
<input type="submit" value="Search"/>
</form>
</p>
<p>
{% for user in queryset %}
<a href="{% url 'main:profile' user.id %}">{{ user.get_full_name }}</a> <br/>
{% endfor %}
</p>
{% endblock %}
forms.py
class SearchForm(forms.Form):
query = forms.CharField(max_length=100, label="", widget=forms.TextInput(attrs={'placeholder': 'Search...'}), required=False)
age_from = forms.IntegerField(label="", widget=forms.NumberInput(attrs={'placeholder': 'Age from'}), required=False)
age_to = forms.IntegerField(label="", widget=forms.NumberInput(attrs={'placeholder': 'Age to'}), required=False)
models.py
UserProfile(models.Model):
sex_choices = (
('Male', 'Male'),
('Female', 'Female'),
('Other', 'Other'),
)
sex = models.CharField(max_length=6,
choices=sex_choices,
default='Male')
birth_date = models.DateField()
如何在与 User
模型具有一对一关系的 UserProfile
模型上添加基于其他字段的搜索选项?
您需要使用相关名称。
由于您尚未共享模型定义,我们假设:
class UserProfile(models.Model):
user = models.OneToOneField(User)
sex = models.CharField(...)
...
因此,当您查询时:
User.objects.filter(user_profile_set__sex='female')
编辑
要根据年龄进行查询,假设您在表单中要求 'age' 并在模型中存储生日,您可以尝试这样的操作:
from datetime import datetime
age = 18 # this shoudl come from form
birth_year = datetime.now().year - age
User.objects.filter(user_profile_set__birth_date__year=birth_year)