django 默认查询条件_Django多条件筛选查询

2023-05-16

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\d+)-(?P\d+)-(?P\d+)-(?P\d+)-(?P\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\d+)-(?P\d+)-(?P\d+)-(?P\d+)-(?P\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,

})

模板设计

事件列表

{% if old_filter %}

{% with filter_event_form.user as filter_fields %}

{{ filter_fields.label }}

{% for select in filter_fields %}{{ select }}{% endfor %}

{% endwith %}

{% with filter_event_form.status as filter_fields %}

{{ filter_fields.label }}

{% for select in filter_fields %}{{ select }}{% endfor %}

{% endwith %}

{% with filter_event_form.project as filter_fields %}

{{ filter_fields.label }}

{% for select in filter_fields %}{{ select }}{% endfor %}

{% endwith %}

{% with filter_event_form.category as filter_fields %}

{{ filter_fields.label }}

{% for select in filter_fields %}{{ select }}{% endfor %}

{% endwith %}

{% with filter_event_form.level as filter_fields %}

{{ filter_fields.label }}

{% for select in filter_fields %}{{ select }}{% endfor %}

{% endwith %}

筛选事件

{% csrf_token %}

{% else %}

用户

{% active_all request.path 1 %}

{% for user_item in user_list %}

{% active request.path user_item 1 %}

{% endfor %}

状态

{% active_all request.path 2 %}

{% for status_item in status_list %}

{% active request.path status_item 2 %}

{% endfor %}

级别

{% active_all request.path 3 %}

{% for level_item in level_list %}

{% active request.path level_item 3 %}

{% endfor %}

分类

{% active_all request.path 4 %}

{% for category_item in category_list %}

{% active request.path category_item 4 %}

{% endfor %}

项目

{% active_all request.path 5 %}

{% for project_item in project_list %}

{% active request.path project_item 5 %}

{% endfor %}

{% endif %}

链接生成模板标签

使用模板标签,在应用下创建templatetags的python包,然后创建active.py文件,需要在模板中通过{% load active %}引入模板标签。

from django.utils.safestring import mark_safe

from django import template

register = template.Library()

@register.simple_tag

def active_all(request_path, index):

url_part_list = request_path.split('-')

# print(url_part_list)

# ['/event', '0', '0', '0', '0', '0.html']

# 第五组带.html,需要分开判断

if url_part_list[index] == '0' or url_part_list[index] == '0.html':

temp = '''

全部

'''

else:

temp = '''

全部

'''

if index != 5:

url_part_list[index] = '0'

else:

url_part_list[index] = '0.html'

href = '-'.join(url_part_list)

return mark_safe(temp.format(href=href))

@register.simple_tag

def active(request_path, item, index):

url_part_list = request_path.split('-')

# 下面判断中,前面表示 event-0-1-5-1-,后面表示 3.html

if url_part_list[index] == str(item['id']) or url_part_list[index] == str(item['id']) + '.html':

temp = '''

{name}

'''

else:

temp = '''

{name}

'''

if index == 5:

# 第五组有后缀.html,需单独处理

url_part_list[index] = str(item['id']) + '.html'

else:

url_part_list[index] = str(item['id'])

href = '-'.join(url_part_list)

if index == 1:

"""

event-1-0-0-0-0.html

event-2-0-0-0-0.html

event-3-0-0-0-0.html

"""

return mark_safe(temp.format(href=href, name=item['username']))

if index == 2:

return mark_safe(temp.format(href=href, name=item['status_tag']))

if index == 3:

return mark_safe(temp.format(href=href, name=item['level_tag']))

if index == 4:

return mark_safe(temp.format(href=href, name=item['category_name']))

if index == 5:

return mark_safe(temp.format(href=href, name=item['project_name']))

两级分类筛选

模型设计

from django.db import models

from django.utils.timezone import now

class GoodsTag(models.Model):

name = models.CharField(max_length=64, verbose_name='标签名称')

def __str__(self):

return self.name

class Meta:

ordering = ['name', ]

verbose_name = '商品标签' # 后台显示模型名称

verbose_name_plural = verbose_name

# 智能家居、手机、电视、电脑

class FirstCategory(models.Model):

name = models.CharField(max_length=64, verbose_name='分类名称')

def __str__(self):

return self.name

class Meta:

ordering = ['name', ]

verbose_name = '一级分类'

verbose_name_plural = verbose_name

# 小米6、小米8、红米10

class SubCategory(models.Model):

name = models.CharField(max_length=64, verbose_name='分类名称')

first_category = models.ForeignKey(FirstCategory, related_name='sub_categories', verbose_name='上级分类')

def __str__(self):

return self.name

class Meta:

ordering = ['name', ]

verbose_name = '二级分类'

verbose_name_plural = verbose_name

class GoodsInfo(models.Model):

STATUS_CHOICES = (

(1, '上架'),

(2, '下架'),

)

title = models.CharField(max_length=100, verbose_name='标题')

content = models.TextField(blank=True, null=True, verbose_name='正文')

image = models.FileField(upload_to='images/goods/%Y/%m', blank=True, null=True, verbose_name='图片')

status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name='状态')

created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

publish_time = models.DateTimeField(blank=True, null=True, default=now, verbose_name='发布时间')

updated_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')

category = models.ForeignKey(SubCategory, on_delete=models.CASCADE, related_name='goods_info', verbose_name='所属分类')

tags = models.ManyToManyField(GoodsTag, blank=True, verbose_name='标签集合')

def __str__(self):

return self.title

class Meta:

verbose_name = '商品信息'

verbose_name_plural = verbose_name

主路由

urlpatterns = [

url(r'^test/', include('multiple_filter.urls', namespace='test')),

]

应用路由

urlpatterns = [

url(r'^goods.html$', goods, name='goods'),

url(r'^goods-(?P\d+)-(?P\d+)-(?P\d+)-(?P\d+).html', goods, name='goods_filter'),

]

视图

from .models import GoodsTag, FirstCategory, SubCategory, GoodsInfo

from django.shortcuts import get_object_or_404

def goods(request, **kwargs):

if not kwargs:

return redirect('test:goods_filter', first_category_id='0', sub_category_id='0', tags_id='0', status_id='0')

else:

request_path = request.path

print('\n当前请求路径:', request_path, '\n')

print('kwargs:', kwargs) # {'first_category_id': '0', 'sub_category_id': '0', 'tags_id': '0', 'status_id': '0'}

goods_tag_list = GoodsTag.objects.all().values('id', 'name')

first_category_list = FirstCategory.objects.all().values('id', 'name')

sub_category_list = SubCategory.objects.all().values('id', 'name')

status_list = list(map(lambda x: {'id': x[0], 'status': x[1]}, GoodsInfo.STATUS_CHOICES))

filter_dict = dict()

if kwargs['first_category_id'] == '0':

# goods-0-x-x-x.html

if kwargs['sub_category_id'] != '0':

# goods-0-1-x-x.html

sub_category = get_object_or_404(SubCategory, id=kwargs['sub_category_id'])

# 选择二级分类后,由于多对一关系,一级分类也会跟着变化

first_category_list = [{'id': sub_category.first_category.id, 'name': sub_category.first_category.name}]

filter_dict['category'] = sub_category

else:

# 一级分类不为0,需要进行筛选

# goods-1-x-x-x.html

first_category = get_object_or_404(FirstCategory, id=kwargs['first_category_id'])

sub_category_list = first_category.sub_categories.values('id', 'name') # 选择一级分类后获取二级分类的列表

if kwargs['sub_category_id'] != '0':

sub_category = get_object_or_404(SubCategory, id=kwargs['sub_category_id'], first_category=first_category)

# 选择二级分类后,由于多对一关系,一级分类也会跟着变化

first_category_list = [{'id': sub_category.first_category.id, 'name': sub_category.first_category.name}]

filter_dict['category'] = sub_category

if kwargs['tags_id'] != '0':

filter_dict['tags'] = kwargs['tags_id']

if kwargs['status_id'] != '0':

filter_dict['status'] = int(kwargs['status_id'])

goods_list = GoodsInfo.objects.filter(**filter_dict)

return render(request, 'goods.html',

{

'first_category_list': first_category_list,

'sub_category_list': sub_category_list,

'goods_tag_list': goods_tag_list,

'status_list': status_list,

'goods_list': goods_list

})

模板

{% load goods_active %}

多条件筛选

{% active_all request.path 1 %}

{% for first_category in first_category_list %}

{% active request.path first_category 1 %}

{% endfor %}

{% active_all request.path 2 %}

{% for sub_category in sub_category_list %}

{% active request.path sub_category 2 %}

{% endfor %}

{% active_all request.path 3 %}

{% for goods_tag in goods_tag_list %}

{% active request.path goods_tag 3 %}

{% endfor %}

{% active_all request.path 4 %}

{% for status in status_list %}

{% active request.path status 4 %}

{% endfor %}

{% for goods in goods_list %}

【{{ goods.title }}】{{ goods.content }}

{% endfor %}

链接生成模板标签

应用下创建templatetags包,创建 goods_active.py 文件,用来放置模板标签

from django.utils.safestring import mark_safe

from django import template

register = template.Library()

@register.simple_tag

def active_all(current_url, index):

"""

获取当前url,进行值修改拼接

:param current_url: http://127.0.0.1:8000/test/goods-0-0-0-0.html

:param index:

:return:

"""

a_href_active = """

【全部】

"""

a_href_unactive = """

全部

"""

url_part_list = current_url.split('-')

if index == len(url_part_list)-1: # 最后一个带.html要特殊处理

if url_part_list[index] == '0.html':

a_href = a_href_active

else:

a_href = a_href_unactive

url_part_list[index] = '0.html'

else:

if url_part_list[index] == '0':

a_href = a_href_active

else:

a_href = a_href_unactive

url_part_list[index] = '0'

href = '-'.join(url_part_list)

a_href = a_href.format(href=href)

return mark_safe(a_href)

@register.simple_tag

def active(current_url, item, index):

"""

获取当前url,进行值修改拼接

:param current_url: http://127.0.0.1:8000/test/goods-0-0-0-0.html

:param index:

:return:

"""

a_href_active = """

【{name}】

"""

a_href_unactive = """

{name}

"""

url_part_list = current_url.split('-')

if index == len(url_part_list)-1: # 最后一个带.html要特殊处理

if url_part_list[index] == str(item['id']) + '.html':

a_href = a_href_active

else:

a_href = a_href_unactive

url_part_list[index] = str(item['id']) + '.html'

else:

# print(item['id'], type(item['id'])) # item['id']是int类型

if url_part_list[index] == str(item['id']):

a_href = a_href_active

else:

a_href = a_href_unactive

url_part_list[index] = str(item['id'])

href = '-'.join(url_part_list)

if index in range(1, 4):

a_href = a_href.format(href=href, name=item['name'])

if index == len(url_part_list)-1:

a_href = a_href.format(href=href, name=item['status'])

return mark_safe(a_href)

多对多模型进行筛选

模型

# 课程分类

class Category(models.Model):

weight = models.IntegerField(verbose_name='权重(按从大到小排列)', default=0)

name = models.CharField(max_length=32, verbose_name='分类名称')

class Meta:

verbose_name = '分类方向'

verbose_name_plural = verbose_name

def __str__(self):

return self.name

# 编程语言,一个课程分类里可能有多种编程语言,一种编程语言可能存在不同的课程分类

class Code(models.Model):

weight = models.IntegerField(default=0, verbose_name='权重(按从大到小排列)')

name = models.CharField(max_length=32, verbose_name='编程语言')

category = models.ManyToManyField(Category, related_name='codes', verbose_name='课程分类')

class Meta:

verbose_name = '编程语言'

verbose_name_plural = verbose_name

def __str__(self):

return self.name

# 课程详情

class Course(models.Model):

STATUS_CHOICE = (

(0, '下线'),

(1, '上线')

)

LEVEL_CHOICE = (

(1, '初级'),

(2, '中级'),

(3, '高级')

)

status = models.IntegerField(choices=STATUS_CHOICE, default=1, verbose_name='状态')

level = models.IntegerField(choices=LEVEL_CHOICE, default=1, verbose_name='难度级别')

category = models.ForeignKey(Category, null=True, blank=True, related_name='courses', verbose_name='课程分类')

weight = models.IntegerField(default=0, verbose_name='权重(按从大到小排列)')

title = models.CharField(max_length=32, verbose_name='标题')

summary = models.CharField(max_length=100, verbose_name='简介')

image = models.ImageField(upload_to='images/course/%Y/%m', verbose_name='图片')

video_url = models.CharField(max_length=256, verbose_name='视频地址')

create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

class Meta:

verbose_name = '课程详情'

verbose_name_plural = verbose_name

def __str__(self):

return self.title

路由

urlpatterns = [

# 访问形式http://127.0.0.1:8000/test/course-0-0-0.html,

# 第一个0代表课程分类,第二个0代表编程语言,第三个0代表课程级别

# 0代表全部,然后递增,当选择课程分类中的第一项,第一个0就会变成1

url(r'^course-(?P\d+)-(?P\d+)-(?P\d+).html', course, name='course'),

]

视图

def course(request, *args, **kwargs):

print(args, kwargs) # () {'code_id': '0', 'category_id': '0', 'level_id': '0'}

request_path = request.path # http://127.0.0.1:8000/test/course-0-0-0.html

# 筛选字典

filter_dict = dict()

code_list = Code.objects.all().values('id', 'name')

category_list = Category.objects.all().values('id', 'name')

level_list = list(map(lambda x: {'id': x[0], 'name': x[1]}, Course.LEVEL_CHOICE))

if kwargs['code_id'] == '0':

if kwargs['category_id'] != '0':

category_list = Category.objects.filter(id=kwargs['category_id']).values('id', 'name')

category = get_object_or_404(Category, id=kwargs['category_id'])

# 分类不是全部,得到这个分类对应的所有编程语言

code_list = category.codes.values('id', 'name')

# 筛选这一分类

filter_dict['category'] = category

else:

# 如果编程语言不为0,则获取对应的编程语言

code = get_object_or_404(Code, id=kwargs['code_id'])

# 得到编程语言对应的所有分类

categories = code.category.all()

category_list = categories.values('id', 'name')

# 筛选课程在这些分类的结果

filter_dict['category__in'] = categories

if kwargs['category_id'] != '0':

# 如果分类不为0,对分类进行筛选,得到该编程语言和该分类下的结果

category = get_object_or_404(categories, id=kwargs['category_id'])

code_list = category.codes.values('id', 'name')

filter_dict['category'] = category

if kwargs['level_id'] != '0':

filter_dict['level'] = int(kwargs['level_id'])

filter_dict['status'] = 1

course_list = Course.objects.filter(**filter_dict)

return render(request, 'course.html',

{

'category_list': category_list,

'code_list': code_list,

'level_list': level_list,

'course_list': course_list,

})

模板

{% load course_active %}

多条件筛选多对多模型

选择:

编程语言:

{% active_all request.path 1 %}

{% for code in code_list %}

{% active request.path code 1 %}

{% endfor %}

课程分类:

{% active_all request.path 2 %}

{% for category in category_list %}

{% active request.path category 2 %}

{% endfor %}

课程信息:

{% active_all request.path 3 %}

{% for level in level_list %}

{% active request.path level 3 %}

{% endfor %}

视频:

{% for course in course_list %}

《{{ course.title }}》{{ course.summary }}


{% endfor %}

链接生成模板标签

应用下创建templatetags包,创建 course_active.py 文件,用来放置模板标签

from django.utils.safestring import mark_safe

from django import template

register = template.Library()

@register.simple_tag

def active_all(current_url, index):

"""

获取当前url, course-1-1-2.html

:param current_url:

:param index:

:return:

"""

url_part_list = current_url.split('-')

if index == 3:

if url_part_list[index] == '0.html':

temp = '【全部】'

else:

temp = '全部'

url_part_list[index] = '0.html'

else:

if url_part_list[index] == '0':

temp = '【全部】'

else:

temp = '全部'

url_part_list[index] = '0'

url_str = '-'.join(url_part_list)

temp = temp % (url_str, )

return mark_safe(temp)

@register.simple_tag

def active(current_url, item, index):

"""

course-0-0-1.html

:param current_url:

:param item:

:param index:

:return:

"""

# print('\n当前访问地址:', current_url, item, index, type(index))

url_part_list = current_url.split('-')

# print(url_part_list) # ['/test/course', '0', '0', '0.html']

if index == 3:

if str(item['id']) == url_part_list[3].split('.')[0]: # 如果当前标签被选中

temp = '【%s】'

else:

temp = '%s'

url_part_list[index] = str(item['id']) + '.html' # 拼接对应位置的url

else:

if str(item['id']) == url_part_list[index]:

temp = '【%s】'

else:

temp = '%s'

url_part_list[index] = str(item['id'])

url_str = '-'.join(url_part_list) # 拼接整体url

# print(url_str)

temp = temp % (url_str, item['name']) # 生成对应的a标签

return mark_safe(temp)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

django 默认查询条件_Django多条件筛选查询 的相关文章

随机推荐