DJANGO:如何对我的查询执行AND操作?

时间:2018-11-25 15:11:09

标签: python django python-3.x django-models django-views

有两种模型。我想进行查询以仅提取与Adspaces相关的与应用完全相同的应用。

models.py

class Appname(models.Model):
     user=models.ForeignKey(User,related_name='appname', null=True, default=None,on_delete=models.CASCADE)  
     name=models.CharField(max_length=150,blank=False,null=False,help_text='Add your new App') 
     def __str__(self):
         return self.name
     def get_absolute_url(self):
         return reverse("dashapp:space",kwargs={'pk':self.pk})


class Adspace(models.Model):
     user=models.ForeignKey(User,related_name='adspace', null=True, default=None,on_delete=models.CASCADE)  
     ad_space=models.CharField(max_length=150,blank=False,null=False) 
     app=models.ForeignKey('Appname', related_name='appnames',default=None, on_delete=models.CASCADE)

     PID_TYPE = (
    ('FN','FORMAT_NATIVE'),
    ('FNB','FORMAT_NATIVE_BANNER'),
    ('FI','FORMAT_INTERSTITIAL'),
    ('FB','FORMAT_BANNER'),
    ('FMR','FORMAT_MEDIUM,RECT'),
    ('FRV','FORMAT_REWARDED_VIDEO'),
)
    format_type=models.CharField(max_length=3,choices=PID_TYPE,default='FN',blank=False, null=False)

    def __str__(self):
         return self.ad_space
    def get_absolute_url(self):
         return reverse("dashapp:create",kwargs={'pk':self.pk})

Views.py

如何查询我需要的那个

      class spacelist(LoginRequiredMixin,ListView):
              model=Adspace
              template_name='adspace_list.html'
              def get_queryset(self):
                       query_set=super().get_queryset()
                       return query_set.filter(user=self.request.user)

在这里,我需要再执行一次查询,以便每个APP都在单击当前每个显示广告空间的应用程序时显示其自己的广告空间。 我有一个主意,好像我比较app_id一样,它将显示与应用程序相关的确切广告空间,但是我不知道如何编写查询,因为我已经有一个查询了。???

2 个答案:

答案 0 :(得分:0)

您可以像这样在末尾链接另一个filter

class spacelist(LoginRequiredMixin,ListView):
    model=Adspace
    template_name='adspace_list.html'

    def get_queryset(self):
        query_set = super().get_queryset()
        query_set = query_set.filter(user=self.request.user)
        app_id = [...]
        return query_set.filter(app_id=app_id)

剩下的问题是找出app_id的来源。您如何知道当前的应用程序是什么?这里有几个选项。

选项1:来自请求

它可以来自当前用户:self.request.user.appname.all(),但这将为您提供多个应用程序,如果用户只能拥有一个应用程序,则应将模型Appname.user更改为OneToOneField

否则,建议您更改related_name='appnames'以反映反向关系中的多重性。

选项2:从URL

它可以来自URL,您的空间列表视图应从其定义的URL中提取一个app_id参数:

url(r'^(?P<app_id>[0-9]+)/spaces/$', spacelist.as_view(), name='space_list'),

然后在空间列表视图中,您将获得如下所示的参数:

app_id = self.kwargs['app_id']
return query_set.filter(app_id=app_id)

希望有帮助

更新:

还值得注意的是QuerySets are lazy,这意味着Django将尽可能晚地评估结果。因此,当您致电:

query_set = query_set.filter(user=self.request.user)

Django ORM尚未执行任何数据库查询,此后您可以链接更多过滤器:

query_set = query_set.filter(user=self.request.user)
query_set = query_set.filter(app_id=app_id)

幕后花絮扩展了将在需要时执行 的查询。但是目前,实际上没有任何查询在运行。要查看将要执行的查询,您可以打印出QuerySet的query属性:

print(query_set.query)

应该记录以下内容:

SELECT "app_adspace"."user_id" ... 
FROM 
  "app_adspace" 
WHERE 
  "app_adspace"."user_id" = 1234 AND "app_adspace"."app_id" = 5678 

答案 1 :(得分:0)

您可以尝试使用Q对象:https://docs.djangoproject.com/en/2.1/topics/db/queries/#complex-lookups-with-q-objects

据我了解,您正在尝试同时过滤app_id和请求用户,因此您可以尝试使用以下代码:

from django.db.models import Q

...
def get_queryset(self):
    query_set=super().get_queryset()
    return query_set.filter(Q(user=self.request.user) & Q(app_id=app_id))
...

这使您可以同时满足两个需求(例如,检索具有特定Adspace的特定user的{​​{1}}实例)。