Python Django request.GET.get метод для URL с операторами if - PullRequest
0 голосов
/ 23 марта 2020

Я бы хотел отфильтровать посты по двум различным категориям: школам и категориям.

models.py

class Category(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'

    def __str__(self):
        return self.name

class School(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'school'
        verbose_name_plural = 'schools'

    def __str__(self):
        return self.name


class VideoPost(models.Model):
    category = models.ForeignKey('Category', on_delete=models.CASCADE)
    school = models.ForeignKey('School', on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique = True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    video = models.CharField(max_length=100, blank=True)
    content = RichTextUploadingField()
    image = models.ImageField(upload_to='images', null=True, blank=True)
    date_posted = models.DateTimeField(default=timezone.now)

    def _get_unique_slug(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(VideoPost, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.title

School и Category - ForeignKeys для VideoPost. Таким образом, в БД он будет иметь только свои идентификаторы, а не слизняк или имя. Это category_id & school_id

views.py

def post_list(request):
    school = request.GET.get('school', None)
    category = request.GET.get('category', None)

    posts = VideoPost.objects.all()

    if school:
        posts.filter(school=school).order_by('-date_posted')

    elif category:
        posts.filter(category=category).order_by('-date_posted')

    elif school & category:
         posts.filter(school=school).filter(category=category).order_by('-date_posted')
    else:
        posts.order_by('-date_posted')

## I wanted to filter them in multiple ways where the posts are filtered by either one of the category, or both, but It doesn't work.
## The only way I found that's working is:

   posts = VideoPost.objects.all().filter(school=school).filter(category=category)
##This way, it filtered the posts with its school and category id specified.

    return render(request, 'stories/browse.html', {'posts': posts})

template. html

<a href="{% url 'post_list' %}?school=1&category=4">Link</a>

Итак, мои вопросы

  1. Возможно ли иметь текст в БД для внешнего ключа? Так что URL может быть более читабельным, и я мог бы использовать текст в теге URL. как <a href="{%url 'post_list' %}?school=MIT&category=sports">Link</a>

  2. Как я могу правильно использовать метод request.GET.get () с оператором IF?

1 Ответ

0 голосов
/ 23 марта 2020
  1. Вы можете фильтровать VideoPost по школьному слагу и слаге категории, вам не нужно указывать первичный ключ поля слагов, обычно это плохой дизайн. Что вы можете сделать, это сделать поле slug уникальным , чтобы вы знали, что нет записей с одинаковыми slug.

  2. Помните, что каждый фильтр, применяемый к QuerySet, будет возвращать новый QuerySet, поэтому вы можете создать цепочку QuerySet.

Следующий код должен работать как положено

school_slug = request.query_params.get('school', None)
category_slug = request.query_params.get('category', None)   

posts = VideoPost.objects.all()

if school:
    # If we have school, filter by school slug
    posts = posts.filter(school__slug=school_slug)
if category:
    # If we have category, filter by category slug
    posts = posts.filter(category__slug=category_slug)

# Always order the posts by date_posted
posts = posts.order_by('-date_posted')

return render(request, 'stories/browse.html', {'posts': posts})

Если оба значения school и category пройдены, мы применяем 2 фильтра к набору запросов

Также в будущем я предложу использовать для этого django -filter случаи использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...