VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Django多条件筛选查询

转自:https://www.jianshu.com/p/a86281df530e

 

Django多条件筛选查询

主模型只存在外键一对多关系

模型设计

# 快捷筛选状态
class Status(models.Model):
    order_number = models.PositiveIntegerField(unique=True, verbose_name='状态编号')
    status_tag = models.CharField(max_length=10, verbose_name='状态名称')

    class Meta:
        ordering = ['order_number', ]
        verbose_name = '事件选择'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.status_tag


# 项目分类
class Project(models.Model):
    project_name = models.CharField(max_length=10, verbose_name='项目名称')

    class Meta:
        ordering = ['project_name']
        verbose_name = '项目分类'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.project_name


# 事件分类
class Category(models.Model):
    category_name = models.CharField(max_length=10, verbose_name='分类名称')

    class Meta:
        ordering = ['category_name', ]
        verbose_name = '事件分类'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.category_name


# 事件级别
class Level(models.Model):
    order_number = models.PositiveIntegerField(unique=True, verbose_name='级别编号')
    level_tag = models.CharField(max_length=10, verbose_name='级别名称')

    class Meta:
        ordering = ['order_number', ]
        verbose_name = '事件级别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.level_tag


# 事件内容
class EventContent(models.Model):
    title = models.CharField(max_length=50, verbose_name='事件标题')
    content = models.TextField(verbose_name='事件正文')
    image = models.ImageField(upload_to='images/%Y/%m', blank=True, null=True, verbose_name='描述图片')
    created = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    status = models.ForeignKey(Status, on_delete=models.SET_NULL, null=True, blank=True, related_name='event_content', verbose_name='事件状态')
    project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, related_name='event_content', verbose_name='项目分类')
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='event_content', verbose_name='事件分类')
    level = models.ForeignKey(Level, on_delete=models.SET_NULL, null=True, blank=True, related_name='event_content', verbose_name='事件级别')
    user = models.ForeignKey(User, related_name='event_content', verbose_name='创建人')
    start_time = models.DateTimeField(default=timezone.now, verbose_name='事件开始时间')
    end_time = models.DateTimeField(default=timezone.now, verbose_name='事件结束时间')
    pause_time = models.DateTimeField(default=timezone.now, verbose_name='事件暂停时间')

    class Meta:
        ordering = ['-created']
        verbose_name = '事件内容'
        verbose_name_plural = verbose_name

    def time_interval(self):
        time_diff = (self.end_time-timezone.now())
        days = time_diff.days
        seconds = time_diff.seconds
        minutes = seconds // 60  # 得到这些秒换算的分钟整数
        second = seconds % 60  # 得到除去分钟后剩余的秒数
        hours = minutes // 60
        minute = minutes % 60
        if self.status.order_number == 6:
            return '事件已关闭!'
        if days <= -1:
            return '处理已超时!'

        return '{}天{}时{}分'.format(days, hours, minute)

    def __str__(self):
        return self.title

    def get_content_as_markdown(self):
        """
        当使用Mardown功能时,我们需要先让它转义一下特殊字符,然后再解析出Markdown标签。
        这样做之后,输出字符串可以安全的在模板中使用。
        :return:
        """
        return mark_safe(markdown(self.content, safe_mode='escape'))

路由设计

    url(r'^event/$', event, name='event'),
    url(r'^event-(?P<user_id>\d+)-(?P<status_id>\d+)-(?P<level_id>\d+)-(?P<category_id>\d+)-(?P<project_id>\d+).html$', event, name='event_filter'),

视图设计

该视图只需要查看kwargs有值的情况

def get_group_url_list(url):
    """
    将访问的url存储在列表中,用于前端判断
    EVENT_MENU_GROUP : 事件菜单组
    OTHER_MENU_GROUP : 其他菜单组
    :param url:
    :return:
    """
    group_url_list = list()
    group_url_list.append(url)
    return group_url_list


# 显示事件列表
def event(request, **kwargs):
    print('视图**kwargs的值:', kwargs)
    if not kwargs:
        # 原来的事件列表和post筛选
        # events = EventContent.objects.all()
        queryset = EventContent.objects.all()
        if request.method == 'POST':
            visit_url = reverse('event')
            event_url_list = get_group_url_list(visit_url)

            filter_event_form = FilterEventForm(request.POST)
            if filter_event_form.is_valid():
                print('表单验证通过')
                user = filter_event_form.cleaned_data['user']
                status = filter_event_form.cleaned_data['status']
                project = filter_event_form.cleaned_data['project']
                category = filter_event_form.cleaned_data['category']
                level = filter_event_form.cleaned_data['level']
                queryset = queryset.filter(user=user, status=status, project=project, category=category, level=level)
                print(queryset)
        else:
            visit_url = reverse('event')
            event_url_list = get_group_url_list(visit_url)

            filter_event_form = FilterEventForm()

        page = request.GET.get('page', 1)
        paginator = Paginator(queryset, settings.PAGE_NUM)  # paginator是分页对象
        try:
            events = paginator.page(page)
        except PageNotAnInteger:
            events = paginator.page(1)
        except EmptyPage:
            events = paginator.page(paginator.num_pages)
        return render(request, 'event.html',
                      {
                          'events': events,
                          'EVENT_MENU_GROUP': event_url_list,
                          'filter_event_form': filter_event_form,
                          'old_filter': True
                      })
    else:
        """
        多条件事件筛选
        event-(?P<user_id>\d+)-(?P<status_id>\d+)-(?P<level_id>\d+)-(?P<category_id>\d+)-(?P<project_id>\d+).html
        {'user_id': '0', 'status_id': '0', 'level_id': '0', 'category_id': '0', 'project_id': '0'}
        """
        filter_dict = dict()
        request_path = request.path
        print('请求地址:', request_path)
        if kwargs['user_id'] != '0':
            filter_dict['user'] = get_object_or_404(User, id=kwargs['user_id'])
        if kwargs['status_id'] != '0':
            filter_dict['status'] = get_object_or_404(Status, id=kwargs['status_id'])
        if kwargs['level_id'] != '0':
            filter_dict['level'] = get_object_or_404(Level, id=kwargs['level_id'])
        if kwargs['category_id'] != '0':
            filter_dict['category'] = get_object_or_404(Category, id=kwargs['category_id'])
        if kwargs['project_id'] != '0':
            filter_dict['project'] = get_object_or_404(Project, id=kwargs['project_id'])

        user_list = User.objects.all().values('id', 'username')
        # print(user_list)
        status_list = Status.objects.all().values('id', 'status_tag')
        # print(status_list)
        level_list = Level.objects.all().values('id', 'level_tag')
        category_list = Category.objects.all().values('id', 'category_name')
        project_list = Project.objects.all().values('id', 'project_name')

        url_id_list = kwargs.values()  # url中所有id:[0, 0, 0, 0, 0 ]
        visit_url = reverse('event_filter', args=url_id_list)
        event_url_list = get_group_url_list(visit_url)
        queryset = EventContent.objects.filter(**filter_dict)
        page = request.GET.get('page', 1)
        paginator = Paginator(queryset, settings.PAGE_NUM)  # paginator是分页对象
        try:
            events = paginator.page(page)
        except PageNotAnInteger:
            events = paginator.page(1)
        except EmptyPage:
            events = paginator.page(paginator.num_pages)
        return render(request, 'event.html',
                      {
                          'events': events,
                          'EVENT_MENU_GROUP': event_url_list,
                          'user_list': user_list,
                          'status_list': status_list,
                          'level_list': level_list,
                          'category_list': category_list,
                          'project_list': project_list,
                      })

模板设计

<div class="card-header">
    <h3 class="card-title">事件列表</h3>
</div>
<!-- /.card-header -->
{% if old_filter %}
    <div class="card-body card-comment">
        <form role="form" action="{% url 'event' %}?page=2" method="post">
            <div class="row">
                <div class="col-2">
                    <div