找不到用于从一个 table 中清除记录的 Django Shell 命令,其中另一个 table 中不存在匹配记录

Can't find Django Shell command to purge records from one table, where matching records DON'T exist in another table

Django/ORM

我有两个 table,我试图在一个 table 中清除/查找所有记录,其中匹配的 table 中不存在匹配的记录。

我正在使用 Django Shell 进行测试,但无法理解要说的命令(用简单的英语)...

Delete/Show all records in my movie table where there are no ratings for it in the ratings table

电影 table(显然)有一个 id 字段,评级 table 有一个匹配的 FK movie_id 字段)

table是:

class Movie(models.Model):
    imdbID = models.TextField(unique=True)
    title = models.TextField()
    year = models.TextField()

class Rating(models.Model):
    movie = models.ForeignKey(Movie,on_delete=CASCADE)
    user = models.ForeignKey(User,on_delete=CASCADE)  
    rating = models.IntegerField()

我有一些 运行 的 Django 命令是(试图接近):

>>> Movie.objects.all()                      ;gives all movies
>>> Rating.objects.all()                     ;gives all ratings
>>> Rating.objects.filter(movie__year=2018)  ;works

但是当我尝试更深入地挖掘时: (试图询问 movie_id 等于评分 movie_id 的电影),我卡住了...

>>> Movie.objects.filter(movie_id=rating__movie)

回溯(最后一次调用): 文件“”,第 1 行,位于 NameError:名称 'rating__movie' 未定义

>>> Movie.objects.filter(rating__movie=movie_id)

回溯(最后一次调用): 文件“”,第 1 行,位于 NameError:名称 'movie_id' 未定义

我真的想要 NOT "WHERE" 条件,但我什至无法获得 TRUE 条件

您正在尝试获取两个模型的数据,但为此您必须使用外键关系 'backward' 的 related_name。您可以在模型定义中设置。

class Rating(models.Model):
    movie = models.ForeignKey(Movie,on_delete=CASCADE, related_name='rating_movie')
    user = models.ForeignKey(User,on_delete=CASCADE, related_name='rating_user')

如果你没有这样做,每一个的名称将是 namemodel_set

现在,例如,获取第一部电影评分的数据。

movie_rated_1 = Rating.objects.get(id=1)
movie = movie_rated_1.rating_movie.all()

更新

我只写了关于如何使用'related names'的例子。对不起。

无论如何...删除没有评论的电影。我认为,您可以使用 difference() 函数和 select_related().

movies_reviewed = Rating.objects.select_related('movie').all()
movies_to_delete = Movie.objects.all().difference(movies_reviewed)
print(movies_reviewed) # To verify
movies_to_delete.delete()

甚至可以写成一行

Movie.objects.all().difference(Rating.objects.select_related('movie').all()).delete()

从 djangoproject.com 的 Ken 那里得到了这个,效果很好...谢谢 Ken ...张贴在这里是为了将来的搜索者的利益。

Movie.objects.filter(rating__isnull=True)  or
Movie.objects.filter(rating__isnull=True).delete()

/fj