我有两个具有明确的多对多关系的模型:一个东西,auth.user和一个连接两者的“最喜欢的”模型。我希望能够通过他们是否被特定用户收藏来命令我的“事物”。在Sqlite3中,我提出的最佳查询是(大致)这个:
select
*, max(u.name = "john cleese") as favorited
from thing as t
join favorite as f on f.thing_id = t.id
join user as u on f.user_id = u.id
group by t.id
order by favorited desc
;
在我的sql-to-django翻译中绊倒我的是max(u.name = "john cleese")
位。据我所知,Django支持算术但不支持平等。我最接近的是一个case语句,它没有正确地对输出行进行分组:
Thing.objects.annotate(favorited=Case(
When(favorites__user=john_cleese, then=Value(True)),
default=Value(False),
output_field=BooleanField()
))
我尝试过的另一个方向是使用RawSQL
:
Thing.objects.annotate(favorited=RawSQL('"auth_user"."username" = "%s"', ["john cleese"]))
但是,这不起作用,因为(据我所知),没有办法明确加入我需要的favorite
和auth_user
表。
我有什么遗失的吗?
答案 0 :(得分:4)
这将实现您(或其他任何人在这里使用Google搜索)想要做的事情:
searchbar.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if(b) hide();
else Utils.closeKeyboard(MapsActivity_v2.this, view);
}
});
<MultiAutoCompleteTextView
android:imeOptions="actionDone"
android:id="@+id/searchbar"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/search_hint"
android:padding="6dp"/>
答案 1 :(得分:1)
根据我在 related ticket 中读到的内容,您可以使用带有 Exists query expression 的子查询。
<块引用>Exists 是一个使用 SQL EXISTS 语句的子查询子类。在许多情况下,它会比子查询执行得更好,因为当找到第一个匹配的行时,数据库能够停止对子查询的评估。
假设您的 ManyToMany 中的中间模型被称为 Favorite
from django.db.models import Exists, OuterRef
is_favorited_subquery = Favorite.objects.filter(
thing_id = OuterRef('pk')
)
Thing.objects.annotate(favorited=Exists(is_favorited_subquery))
然后您可以通过查询的 favorited
属性进行排序。
答案 2 :(得分:0)
我不确定你想要达到的目标,但我会这样开始。
from django.db import models
from django.contrib.auth.models import User
class MyUser(models.Model):
person = models.OneToOneField(User)
class Thing(models.Model):
thingname = models.CharField(max_length=10)
favorited_by = models.ManyToManyField(MyUser)
在你看来:
qs = MyUser.objects.get(id=pk_of_user_john_reese).thing_set.all()
将为您提供给定用户的所有Thing对象。
您应该查看Django Docs for ManyToMany
我在几个较小甚至更大的项目中使用Django已经有好几年了,但我从不使用了RawSQL功能。大多数时候我都在考虑它,我的模型设计中有一个错误。