热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

Django多条件筛选查询主模型只存在外键一对多关系模型设计#快捷筛选状态classStatus(models.Model):order_numbermodels.Positive

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 <&#61; -1:

return &#39;处理已超时&#xff01;&#39;

return &#39;{}天{}时{}分&#39;.format(days, hours, minute)

def __str__(self):

return self.title

def get_content_as_markdown(self):

"""

当使用Mardown功能时&#xff0c;我们需要先让它转义一下特殊字符&#xff0c;然后再解析出Markdown标签。

这样做之后&#xff0c;输出字符串可以安全的在模板中使用。

:return:

"""

return mark_safe(markdown(self.content, safe_mode&#61;&#39;escape&#39;))

路由设计

url(r&#39;^event/$&#39;, event, name&#61;&#39;event&#39;),

url(r&#39;^event-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;).html$&#39;, event, name&#61;&#39;event_filter&#39;),

视图设计

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

def get_group_url_list(url):

"""

将访问的url存储在列表中&#xff0c;用于前端判断

EVENT_MENU_GROUP : 事件菜单组

OTHER_MENU_GROUP : 其他菜单组

:param url:

:return:

"""

group_url_list &#61; list()

group_url_list.append(url)

return group_url_list

# 显示事件列表

def event(request, **kwargs):

print(&#39;视图**kwargs的值&#xff1a;&#39;, kwargs)

if not kwargs:

# 原来的事件列表和post筛选

# events &#61; EventContent.objects.all()

queryset &#61; EventContent.objects.all()

if request.method &#61;&#61; &#39;POST&#39;:

visit_url &#61; reverse(&#39;event&#39;)

event_url_list &#61; get_group_url_list(visit_url)

filter_event_form &#61; FilterEventForm(request.POST)

if filter_event_form.is_valid():

print(&#39;表单验证通过&#39;)

user &#61; filter_event_form.cleaned_data[&#39;user&#39;]

status &#61; filter_event_form.cleaned_data[&#39;status&#39;]

project &#61; filter_event_form.cleaned_data[&#39;project&#39;]

category &#61; filter_event_form.cleaned_data[&#39;category&#39;]

level &#61; filter_event_form.cleaned_data[&#39;level&#39;]

queryset &#61; queryset.filter(user&#61;user, status&#61;status, project&#61;project, category&#61;category, level&#61;level)

print(queryset)

else:

visit_url &#61; reverse(&#39;event&#39;)

event_url_list &#61; get_group_url_list(visit_url)

filter_event_form &#61; FilterEventForm()

page &#61; request.GET.get(&#39;page&#39;, 1)

paginator &#61; Paginator(queryset, settings.PAGE_NUM) # paginator是分页对象

try:

events &#61; paginator.page(page)

except PageNotAnInteger:

events &#61; paginator.page(1)

except EmptyPage:

events &#61; paginator.page(paginator.num_pages)

return render(request, &#39;event.html&#39;,

{

&#39;events&#39;: events,

&#39;EVENT_MENU_GROUP&#39;: event_url_list,

&#39;filter_event_form&#39;: filter_event_form,

&#39;old_filter&#39;: True

})

else:

"""

多条件事件筛选

event-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;).html

{&#39;user_id&#39;: &#39;0&#39;, &#39;status_id&#39;: &#39;0&#39;, &#39;level_id&#39;: &#39;0&#39;, &#39;category_id&#39;: &#39;0&#39;, &#39;project_id&#39;: &#39;0&#39;}

"""

filter_dict &#61; dict()

request_path &#61; request.path

print(&#39;请求地址&#xff1a;&#39;, request_path)

if kwargs[&#39;user_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;user&#39;] &#61; get_object_or_404(User, id&#61;kwargs[&#39;user_id&#39;])

if kwargs[&#39;status_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;status&#39;] &#61; get_object_or_404(Status, id&#61;kwargs[&#39;status_id&#39;])

if kwargs[&#39;level_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;level&#39;] &#61; get_object_or_404(Level, id&#61;kwargs[&#39;level_id&#39;])

if kwargs[&#39;category_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;category&#39;] &#61; get_object_or_404(Category, id&#61;kwargs[&#39;category_id&#39;])

if kwargs[&#39;project_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;project&#39;] &#61; get_object_or_404(Project, id&#61;kwargs[&#39;project_id&#39;])

user_list &#61; User.objects.all().values(&#39;id&#39;, &#39;username&#39;)

# print(user_list)

status_list &#61; Status.objects.all().values(&#39;id&#39;, &#39;status_tag&#39;)

# print(status_list)

level_list &#61; Level.objects.all().values(&#39;id&#39;, &#39;level_tag&#39;)

category_list &#61; Category.objects.all().values(&#39;id&#39;, &#39;category_name&#39;)

project_list &#61; Project.objects.all().values(&#39;id&#39;, &#39;project_name&#39;)

url_id_list &#61; kwargs.values() # url中所有id&#xff1a;[0, 0, 0, 0, 0 ]

visit_url &#61; reverse(&#39;event_filter&#39;, args&#61;url_id_list)

event_url_list &#61; get_group_url_list(visit_url)

queryset &#61; EventContent.objects.filter(**filter_dict)

page &#61; request.GET.get(&#39;page&#39;, 1)

paginator &#61; Paginator(queryset, settings.PAGE_NUM) # paginator是分页对象

try:

events &#61; paginator.page(page)

except PageNotAnInteger:

events &#61; paginator.page(1)

except EmptyPage:

events &#61; paginator.page(paginator.num_pages)

return render(request, &#39;event.html&#39;,

{

&#39;events&#39;: events,

&#39;EVENT_MENU_GROUP&#39;: event_url_list,

&#39;user_list&#39;: user_list,

&#39;status_list&#39;: status_list,

&#39;level_list&#39;: level_list,

&#39;category_list&#39;: category_list,

&#39;project_list&#39;: 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 %}

链接生成模板标签

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

from django.utils.safestring import mark_safe

from django import template

register &#61; template.Library()

&#64;register.simple_tag

def active_all(request_path, index):

url_part_list &#61; request_path.split(&#39;-&#39;)

# print(url_part_list)

# [&#39;/event&#39;, &#39;0&#39;, &#39;0&#39;, &#39;0&#39;, &#39;0&#39;, &#39;0.html&#39;]

# 第五组带.html&#xff0c;需要分开判断

if url_part_list[index] &#61;&#61; &#39;0&#39; or url_part_list[index] &#61;&#61; &#39;0.html&#39;:

temp &#61; &#39;&#39;&#39;

全部

&#39;&#39;&#39;

else:

temp &#61; &#39;&#39;&#39;

全部

&#39;&#39;&#39;

if index !&#61; 5:

url_part_list[index] &#61; &#39;0&#39;

else:

url_part_list[index] &#61; &#39;0.html&#39;

href &#61; &#39;-&#39;.join(url_part_list)

return mark_safe(temp.format(href&#61;href))

&#64;register.simple_tag

def active(request_path, item, index):

url_part_list &#61; request_path.split(&#39;-&#39;)

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

if url_part_list[index] &#61;&#61; str(item[&#39;id&#39;]) or url_part_list[index] &#61;&#61; str(item[&#39;id&#39;]) &#43; &#39;.html&#39;:

temp &#61; &#39;&#39;&#39;

{name}

&#39;&#39;&#39;

else:

temp &#61; &#39;&#39;&#39;

{name}

&#39;&#39;&#39;

if index &#61;&#61; 5:

# 第五组有后缀.html&#xff0c;需单独处理

url_part_list[index] &#61; str(item[&#39;id&#39;]) &#43; &#39;.html&#39;

else:

url_part_list[index] &#61; str(item[&#39;id&#39;])

href &#61; &#39;-&#39;.join(url_part_list)

if index &#61;&#61; 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&#61;href, name&#61;item[&#39;username&#39;]))

if index &#61;&#61; 2:

return mark_safe(temp.format(href&#61;href, name&#61;item[&#39;status_tag&#39;]))

if index &#61;&#61; 3:

return mark_safe(temp.format(href&#61;href, name&#61;item[&#39;level_tag&#39;]))

if index &#61;&#61; 4:

return mark_safe(temp.format(href&#61;href, name&#61;item[&#39;category_name&#39;]))

if index &#61;&#61; 5:

return mark_safe(temp.format(href&#61;href, name&#61;item[&#39;project_name&#39;]))

两级分类筛选

模型设计

from django.db import models

from django.utils.timezone import now

class GoodsTag(models.Model):

name &#61; models.CharField(max_length&#61;64, verbose_name&#61;&#39;标签名称&#39;)

def __str__(self):

return self.name

class Meta:

ordering &#61; [&#39;name&#39;, ]

verbose_name &#61; &#39;商品标签&#39; # 后台显示模型名称

verbose_name_plural &#61; verbose_name

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

class FirstCategory(models.Model):

name &#61; models.CharField(max_length&#61;64, verbose_name&#61;&#39;分类名称&#39;)

def __str__(self):

return self.name

class Meta:

ordering &#61; [&#39;name&#39;, ]

verbose_name &#61; &#39;一级分类&#39;

verbose_name_plural &#61; verbose_name

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

class SubCategory(models.Model):

name &#61; models.CharField(max_length&#61;64, verbose_name&#61;&#39;分类名称&#39;)

first_category &#61; models.ForeignKey(FirstCategory, related_name&#61;&#39;sub_categories&#39;, verbose_name&#61;&#39;上级分类&#39;)

def __str__(self):

return self.name

class Meta:

ordering &#61; [&#39;name&#39;, ]

verbose_name &#61; &#39;二级分类&#39;

verbose_name_plural &#61; verbose_name

class GoodsInfo(models.Model):

STATUS_CHOICES &#61; (

(1, &#39;上架&#39;),

(2, &#39;下架&#39;),

)

title &#61; models.CharField(max_length&#61;100, verbose_name&#61;&#39;标题&#39;)

content &#61; models.TextField(blank&#61;True, null&#61;True, verbose_name&#61;&#39;正文&#39;)

image &#61; models.FileField(upload_to&#61;&#39;images/goods/%Y/%m&#39;, blank&#61;True, null&#61;True, verbose_name&#61;&#39;图片&#39;)

status &#61; models.IntegerField(choices&#61;STATUS_CHOICES, default&#61;1, verbose_name&#61;&#39;状态&#39;)

created_time &#61; models.DateTimeField(auto_now_add&#61;True, verbose_name&#61;&#39;创建时间&#39;)

publish_time &#61; models.DateTimeField(blank&#61;True, null&#61;True, default&#61;now, verbose_name&#61;&#39;发布时间&#39;)

updated_time &#61; models.DateTimeField(auto_now&#61;True, verbose_name&#61;&#39;更新时间&#39;)

category &#61; models.ForeignKey(SubCategory, on_delete&#61;models.CASCADE, related_name&#61;&#39;goods_info&#39;, verbose_name&#61;&#39;所属分类&#39;)

tags &#61; models.ManyToManyField(GoodsTag, blank&#61;True, verbose_name&#61;&#39;标签集合&#39;)

def __str__(self):

return self.title

class Meta:

verbose_name &#61; &#39;商品信息&#39;

verbose_name_plural &#61; verbose_name

主路由

urlpatterns &#61; [

url(r&#39;^test/&#39;, include(&#39;multiple_filter.urls&#39;, namespace&#61;&#39;test&#39;)),

]

应用路由

urlpatterns &#61; [

url(r&#39;^goods.html$&#39;, goods, name&#61;&#39;goods&#39;),

url(r&#39;^goods-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;).html&#39;, goods, name&#61;&#39;goods_filter&#39;),

]

视图

from .models import GoodsTag, FirstCategory, SubCategory, GoodsInfo

from django.shortcuts import get_object_or_404

def goods(request, **kwargs):

if not kwargs:

return redirect(&#39;test:goods_filter&#39;, first_category_id&#61;&#39;0&#39;, sub_category_id&#61;&#39;0&#39;, tags_id&#61;&#39;0&#39;, status_id&#61;&#39;0&#39;)

else:

request_path &#61; request.path

print(&#39;\n当前请求路径&#xff1a;&#39;, request_path, &#39;\n&#39;)

print(&#39;kwargs&#xff1a;&#39;, kwargs) # {&#39;first_category_id&#39;: &#39;0&#39;, &#39;sub_category_id&#39;: &#39;0&#39;, &#39;tags_id&#39;: &#39;0&#39;, &#39;status_id&#39;: &#39;0&#39;}

goods_tag_list &#61; GoodsTag.objects.all().values(&#39;id&#39;, &#39;name&#39;)

first_category_list &#61; FirstCategory.objects.all().values(&#39;id&#39;, &#39;name&#39;)

sub_category_list &#61; SubCategory.objects.all().values(&#39;id&#39;, &#39;name&#39;)

status_list &#61; list(map(lambda x: {&#39;id&#39;: x[0], &#39;status&#39;: x[1]}, GoodsInfo.STATUS_CHOICES))

filter_dict &#61; dict()

if kwargs[&#39;first_category_id&#39;] &#61;&#61; &#39;0&#39;:

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

if kwargs[&#39;sub_category_id&#39;] !&#61; &#39;0&#39;:

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

sub_category &#61; get_object_or_404(SubCategory, id&#61;kwargs[&#39;sub_category_id&#39;])

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

first_category_list &#61; [{&#39;id&#39;: sub_category.first_category.id, &#39;name&#39;: sub_category.first_category.name}]

filter_dict[&#39;category&#39;] &#61; sub_category

else:

# 一级分类不为0&#xff0c;需要进行筛选

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

first_category &#61; get_object_or_404(FirstCategory, id&#61;kwargs[&#39;first_category_id&#39;])

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

if kwargs[&#39;sub_category_id&#39;] !&#61; &#39;0&#39;:

sub_category &#61; get_object_or_404(SubCategory, id&#61;kwargs[&#39;sub_category_id&#39;], first_category&#61;first_category)

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

first_category_list &#61; [{&#39;id&#39;: sub_category.first_category.id, &#39;name&#39;: sub_category.first_category.name}]

filter_dict[&#39;category&#39;] &#61; sub_category

if kwargs[&#39;tags_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;tags&#39;] &#61; kwargs[&#39;tags_id&#39;]

if kwargs[&#39;status_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;status&#39;] &#61; int(kwargs[&#39;status_id&#39;])

goods_list &#61; GoodsInfo.objects.filter(**filter_dict)

return render(request, &#39;goods.html&#39;,

{

&#39;first_category_list&#39;: first_category_list,

&#39;sub_category_list&#39;: sub_category_list,

&#39;goods_tag_list&#39;: goods_tag_list,

&#39;status_list&#39;: status_list,

&#39;goods_list&#39;: 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包&#xff0c;创建 goods_active.py 文件&#xff0c;用来放置模板标签

from django.utils.safestring import mark_safe

from django import template

register &#61; template.Library()

&#64;register.simple_tag

def active_all(current_url, index):

"""

获取当前url&#xff0c;进行值修改拼接

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

:param index:

:return:

"""

a_href_active &#61; """

【全部】

"""

a_href_unactive &#61; """

全部

"""

url_part_list &#61; current_url.split(&#39;-&#39;)

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

if url_part_list[index] &#61;&#61; &#39;0.html&#39;:

a_href &#61; a_href_active

else:

a_href &#61; a_href_unactive

url_part_list[index] &#61; &#39;0.html&#39;

else:

if url_part_list[index] &#61;&#61; &#39;0&#39;:

a_href &#61; a_href_active

else:

a_href &#61; a_href_unactive

url_part_list[index] &#61; &#39;0&#39;

href &#61; &#39;-&#39;.join(url_part_list)

a_href &#61; a_href.format(href&#61;href)

return mark_safe(a_href)

&#64;register.simple_tag

def active(current_url, item, index):

"""

获取当前url&#xff0c;进行值修改拼接

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

:param index:

:return:

"""

a_href_active &#61; """

【{name}】

"""

a_href_unactive &#61; """

{name}

"""

url_part_list &#61; current_url.split(&#39;-&#39;)

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

if url_part_list[index] &#61;&#61; str(item[&#39;id&#39;]) &#43; &#39;.html&#39;:

a_href &#61; a_href_active

else:

a_href &#61; a_href_unactive

url_part_list[index] &#61; str(item[&#39;id&#39;]) &#43; &#39;.html&#39;

else:

# print(item[&#39;id&#39;], type(item[&#39;id&#39;])) # item[&#39;id&#39;]是int类型

if url_part_list[index] &#61;&#61; str(item[&#39;id&#39;]):

a_href &#61; a_href_active

else:

a_href &#61; a_href_unactive

url_part_list[index] &#61; str(item[&#39;id&#39;])

href &#61; &#39;-&#39;.join(url_part_list)

if index in range(1, 4):

a_href &#61; a_href.format(href&#61;href, name&#61;item[&#39;name&#39;])

if index &#61;&#61; len(url_part_list)-1:

a_href &#61; a_href.format(href&#61;href, name&#61;item[&#39;status&#39;])

return mark_safe(a_href)

多对多模型进行筛选

模型

# 课程分类

class Category(models.Model):

weight &#61; models.IntegerField(verbose_name&#61;&#39;权重(按从大到小排列)&#39;, default&#61;0)

name &#61; models.CharField(max_length&#61;32, verbose_name&#61;&#39;分类名称&#39;)

class Meta:

verbose_name &#61; &#39;分类方向&#39;

verbose_name_plural &#61; verbose_name

def __str__(self):

return self.name

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

class Code(models.Model):

weight &#61; models.IntegerField(default&#61;0, verbose_name&#61;&#39;权重(按从大到小排列)&#39;)

name &#61; models.CharField(max_length&#61;32, verbose_name&#61;&#39;编程语言&#39;)

category &#61; models.ManyToManyField(Category, related_name&#61;&#39;codes&#39;, verbose_name&#61;&#39;课程分类&#39;)

class Meta:

verbose_name &#61; &#39;编程语言&#39;

verbose_name_plural &#61; verbose_name

def __str__(self):

return self.name

# 课程详情

class Course(models.Model):

STATUS_CHOICE &#61; (

(0, &#39;下线&#39;),

(1, &#39;上线&#39;)

)

LEVEL_CHOICE &#61; (

(1, &#39;初级&#39;),

(2, &#39;中级&#39;),

(3, &#39;高级&#39;)

)

status &#61; models.IntegerField(choices&#61;STATUS_CHOICE, default&#61;1, verbose_name&#61;&#39;状态&#39;)

level &#61; models.IntegerField(choices&#61;LEVEL_CHOICE, default&#61;1, verbose_name&#61;&#39;难度级别&#39;)

category &#61; models.ForeignKey(Category, null&#61;True, blank&#61;True, related_name&#61;&#39;courses&#39;, verbose_name&#61;&#39;课程分类&#39;)

weight &#61; models.IntegerField(default&#61;0, verbose_name&#61;&#39;权重(按从大到小排列)&#39;)

title &#61; models.CharField(max_length&#61;32, verbose_name&#61;&#39;标题&#39;)

summary &#61; models.CharField(max_length&#61;100, verbose_name&#61;&#39;简介&#39;)

image &#61; models.ImageField(upload_to&#61;&#39;images/course/%Y/%m&#39;, verbose_name&#61;&#39;图片&#39;)

video_url &#61; models.CharField(max_length&#61;256, verbose_name&#61;&#39;视频地址&#39;)

create_time &#61; models.DateTimeField(auto_now_add&#61;True, verbose_name&#61;&#39;创建时间&#39;)

class Meta:

verbose_name &#61; &#39;课程详情&#39;

verbose_name_plural &#61; verbose_name

def __str__(self):

return self.title

路由

urlpatterns &#61; [

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

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

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

url(r&#39;^course-(?P\d&#43;)-(?P\d&#43;)-(?P\d&#43;).html&#39;, course, name&#61;&#39;course&#39;),

]

视图

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

print(args, kwargs) # () {&#39;code_id&#39;: &#39;0&#39;, &#39;category_id&#39;: &#39;0&#39;, &#39;level_id&#39;: &#39;0&#39;}

request_path &#61; request.path # http://127.0.0.1:8000/test/course-0-0-0.html

# 筛选字典

filter_dict &#61; dict()

code_list &#61; Code.objects.all().values(&#39;id&#39;, &#39;name&#39;)

category_list &#61; Category.objects.all().values(&#39;id&#39;, &#39;name&#39;)

level_list &#61; list(map(lambda x: {&#39;id&#39;: x[0], &#39;name&#39;: x[1]}, Course.LEVEL_CHOICE))

if kwargs[&#39;code_id&#39;] &#61;&#61; &#39;0&#39;:

if kwargs[&#39;category_id&#39;] !&#61; &#39;0&#39;:

category_list &#61; Category.objects.filter(id&#61;kwargs[&#39;category_id&#39;]).values(&#39;id&#39;, &#39;name&#39;)

category &#61; get_object_or_404(Category, id&#61;kwargs[&#39;category_id&#39;])

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

code_list &#61; category.codes.values(&#39;id&#39;, &#39;name&#39;)

# 筛选这一分类

filter_dict[&#39;category&#39;] &#61; category

else:

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

code &#61; get_object_or_404(Code, id&#61;kwargs[&#39;code_id&#39;])

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

categories &#61; code.category.all()

category_list &#61; categories.values(&#39;id&#39;, &#39;name&#39;)

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

filter_dict[&#39;category__in&#39;] &#61; categories

if kwargs[&#39;category_id&#39;] !&#61; &#39;0&#39;:

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

category &#61; get_object_or_404(categories, id&#61;kwargs[&#39;category_id&#39;])

code_list &#61; category.codes.values(&#39;id&#39;, &#39;name&#39;)

filter_dict[&#39;category&#39;] &#61; category

if kwargs[&#39;level_id&#39;] !&#61; &#39;0&#39;:

filter_dict[&#39;level&#39;] &#61; int(kwargs[&#39;level_id&#39;])

filter_dict[&#39;status&#39;] &#61; 1

course_list &#61; Course.objects.filter(**filter_dict)

return render(request, &#39;course.html&#39;,

{

&#39;category_list&#39;: category_list,

&#39;code_list&#39;: code_list,

&#39;level_list&#39;: level_list,

&#39;course_list&#39;: course_list,

})

模板

{% load course_active %}

多条件筛选多对多模型

选择&#xff1a;

编程语言&#xff1a;

{% active_all request.path 1 %}

{% for code in code_list %}

{% active request.path code 1 %}

{% endfor %}

课程分类&#xff1a;

{% active_all request.path 2 %}

{% for category in category_list %}

{% active request.path category 2 %}

{% endfor %}

课程信息&#xff1a;

{% active_all request.path 3 %}

{% for level in level_list %}

{% active request.path level 3 %}

{% endfor %}

视频&#xff1a;

{% for course in course_list %}

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


{% endfor %}

链接生成模板标签

应用下创建templatetags包&#xff0c;创建 course_active.py 文件&#xff0c;用来放置模板标签

from django.utils.safestring import mark_safe

from django import template

register &#61; template.Library()

&#64;register.simple_tag

def active_all(current_url, index):

"""

获取当前url&#xff0c; course-1-1-2.html

:param current_url:

:param index:

:return:

"""

url_part_list &#61; current_url.split(&#39;-&#39;)

if index &#61;&#61; 3:

if url_part_list[index] &#61;&#61; &#39;0.html&#39;:

temp &#61; &#39;【全部】&#39;

else:

temp &#61; &#39;全部&#39;

url_part_list[index] &#61; &#39;0.html&#39;

else:

if url_part_list[index] &#61;&#61; &#39;0&#39;:

temp &#61; &#39;【全部】&#39;

else:

temp &#61; &#39;全部&#39;

url_part_list[index] &#61; &#39;0&#39;

url_str &#61; &#39;-&#39;.join(url_part_list)

temp &#61; temp % (url_str, )

return mark_safe(temp)

&#64;register.simple_tag

def active(current_url, item, index):

"""

course-0-0-1.html

:param current_url:

:param item:

:param index:

:return:

"""

# print(&#39;\n当前访问地址&#xff1a;&#39;, current_url, item, index, type(index))

url_part_list &#61; current_url.split(&#39;-&#39;)

# print(url_part_list) # [&#39;/test/course&#39;, &#39;0&#39;, &#39;0&#39;, &#39;0.html&#39;]

if index &#61;&#61; 3:

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

temp &#61; &#39;【%s】&#39;

else:

temp &#61; &#39;%s&#39;

url_part_list[index] &#61; str(item[&#39;id&#39;]) &#43; &#39;.html&#39; # 拼接对应位置的url

else:

if str(item[&#39;id&#39;]) &#61;&#61; url_part_list[index]:

temp &#61; &#39;【%s】&#39;

else:

temp &#61; &#39;%s&#39;

url_part_list[index] &#61; str(item[&#39;id&#39;])

url_str &#61; &#39;-&#39;.join(url_part_list) # 拼接整体url

# print(url_str)

temp &#61; temp % (url_str, item[&#39;name&#39;]) # 生成对应的a标签

return mark_safe(temp)



推荐阅读
author-avatar
血流的风霜_565
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有