DJANGO: Как выполнить операцию И для моего запроса? - PullRequest
0 голосов
/ 25 ноября 2018

Существует две модели. Я хочу сделать запрос для извлечения только точного приложения, связанного с приложением 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_id, тогда он покажет точное пространство, связанное с приложением, но я не знаю, как написать запрос для того же, так как у меня уже есть один запрос .???

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Вы можете попробовать использовать объекты 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 с определенным Appname).

0 голосов
/ 25 ноября 2018

Вы добавляете в цепочку еще один 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, вашегопредставление списка пространств должно извлечь параметр app_id из URL-адреса, где он определен:

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 являются ленивыми , что означает, что результат будет оценен Django как можно позже.Поэтому при вызове:

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

ORM Django еще не выполняет никаких запросов к БД, и после этого вы можете связать больше фильтров:

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

Что за кадромрасширение запроса на выполнение при необходимости.Но на данный момент ни один запрос на самом деле не выполняется.Чтобы увидеть запрос, который будет выполнен, вы можете распечатать атрибут query QuerySet:

print(query_set.query)

, который должен регистрировать что-то вроде:

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