我正在编写一项匹配服务,该服务将根据重叠的专业知识将您与个人资料匹配。例如。如果您需要python的专业知识,它将为您提供python的专业知识。
我无法确定如何使用Django ORM构建该查询。
我有模特:
class Profile(models.Model):
pass
class Expertise(models.Model):
profile = db.ForeignKey('profile', on_delete=models.CASCADE)
name = db.CharField(choices=[(1, 'python'), (2, 'javascript'), (3, 'golang')], max_length =255)
direction = db.CharField(choices=[('offered', 'offered'), ('requested', 'requested')], max_length = 255)
我的数据基本上如下所示:
# setup some fields
profile = Profile()
profile.save()
Expertise(profile=profile, name=1, direction='requested').save()
Expertise(profile=profile, name=2, direction='offered').save()
Profile.objects.filter(
expertise__name__in = [e.name for e in profile.expertise_set()]
expertise__direction__in = [e.direction for e in profile.expertise_set()]
)
我实质上是在寻找在查询中结合布尔AND和布尔OR的功能。
在SQL中,我会按照以下方式进行操作:
SELECT * FROM app_profiles JOIN app_expertise on app_profiles.id = app_expertise.app_profiles_id
WHERE
(app_expertise.direction = 'offered' AND app_expertise.name = 1) OR
(app_expertise.direction = 'requested' AND app_expertise.name = 2)
>>> maus = Profile.objects.get_or_create(name='Maus')[0]
>>> kungphu = Profile.objects.get_or_create(name='kungphu')[0]
>>> strange = Profile.objects.get_or_create(name='Dr. Strange')[0]
>>> thanos = Profile.objects.get_or_create(name='thanos')[0]
>>>
>>> # maus offers golang and requests python
>>> Expertise.objects.get_or_create(
... profile=maus,
... name=Expertise.NAME_PYTHON,
... direction=Expertise.DIRECTION_REQUESTED,
... )[0]
<Expertise: Python (Requested by Maus)>
>>> Expertise.objects.get_or_create(
... profile=maus,
... name=Expertise.NAME_GOLANG,
... direction=Expertise.DIRECTION_OFFERED,
... )[0]
<Expertise: Golang (Offered by Maus)>
>>> # kungphu offers python and requests golang, they will match
>>> # with mous both because of golang and python compatibility
>>> Expertise.objects.get_or_create(
... profile=kungphu,
... name=Expertise.NAME_PYTHON,
... direction=Expertise.DIRECTION_OFFERED,
... )[0]
<Expertise: Python (Requested by kungphu)>
>>> Expertise.objects.get_or_create(
... profile=kungphu,
... name=Expertise.NAME_GOLANG,
... direction=Expertise.DIRECTION_REQUESTED,
... )[0]
<Expertise:Golang (Requested by kungphu)>
>>> # Doctor Strange is trying to learn golang, he will match with maus as
>>> # a result.
>>> Expertise.objects.get_or_create(
... profile=kungphu,
... name=Expertise.NAME_GOLANG,
... direction=Expertise.DIRECTION_REQUESTED,
... )[0]
<Expertise:Golang (Requested by strange)>
>>>
>>> # Thanos both offers and requests Python, because balance, I guess.
>>> Expertise.objects.get_or_create(
... profile=thanos,
... name=Expertise.NAME_PYTHON,
... direction=Expertise.DIRECTION_REQUESTED,
... )[0]
<Expertise: Python (Requested by thanos)>
>>> Expertise.objects.get_or_create(
... profile=thanos,
... name=Expertise.NAME_PYTHON,
... direction=Expertise.DIRECTION_OFFERED,
... )[0]
<Expertise: Python (Offered by thanos)>
>>>
>>> # maus has requested Python, thanos and kungphu have offered it
>>> # maus has offered golang, dr. strange and kungphu have requested it.
>>> maus.find_matches()
[<Profile: kungphu>, <Profile: thanos>, <Profile: strange>]
答案 0 :(得分:1)
对于复杂的查询,Django提供了Q
objects
所以您可以使用Q对象查询该表;
Expertise.objects.select_related('profile').filter(
(Q(direction='offered') & Q(name=1)) | (Q(direction='requested') & Q(name=2))
)
|
是OR
,而&
是不言自明的。您也可以对~Q
样式查询进行NOT
。
select_related
(如果您还没有遇到过的话)对相关对象进行更有效的查询。您可以在此处了解更多信息。 https://medium.com/@lucasmagnum/djangotip-select-prefetch-related-e76b683aa457