一、项目定位:
本人以团队小组开发的项目功能为例,为大家分享"智能鸟类识别平台"的搜索功能和喜欢功能;博客内容侧重于后端业务逻辑的实现,前端页面由于内容过多,只展示部分关键代码;如有问题,欢迎沟通交流!后续可能会跟进更多功能的分享。
智能鸟类识别平台在于模拟鸟类爱好者/学者等用户使用toC平台时的场景, 用户可以直观的通过平台,观察和记录鸟类保护动物的照片和信息, 以甄别分类、实况分析鸟类保护动物,与全世界各地的用户沟通交流。
模糊查询搜索对应了鸟类档案馆中的功能,用户可以模糊查询档案馆中所有录入的鸟类信息(如下图所示):
此外,对于用户观察到的鸟类数据,在识别出结果后(CNN卷积神经网络实现),点击科普知识后,可以选择喜欢/不喜欢,以此针对档案馆中的人气值数据,实现增加或减少的统计:
点击科普知识跳转到上面的页面时,涉及关联查询的功能实现,有兴趣了解的朋友可以看这篇文章:提升 Django ORM 的查询效率:关联查询与普通查询的实战对比)。
二 、模型构建:
在应用birds中的models.py中编写实体鸟类的数据模型代码:
class Bird(models.Model):
id = models.AutoField(primary_key=True)
images = models.CharField(verbose_name='鸟类图片', max_length=255)
name = models.CharField(verbose_name='鸟类名称', max_length=50)
order = models.CharField(verbose_name='目', max_length=50) # 鸟类所属的目
family = models.CharField(verbose_name='科', max_length=50) # 鸟类所属的科
genus = models.CharField(verbose_name='科', max_length=50) # 鸟类所属的属
size = models.CharField(verbose_name='体型描述', max_length=100) # 鸟类的体型描述,如长度、翼展、重量等
plumage = models.CharField(verbose_name='羽毛描述', max_length=255) # 羽毛的颜色和图案
habitat = models.CharField(verbose_name='栖息地分布', max_length=100) # 鸟类的栖息地,如森林、湿地、草原等
distribution = models.CharField(verbose_name='地理分布', max_length=255) # 鸟类的地理分布范围
iucn_status = models.CharField(verbose_name='保护等级', max_length=50) # 根据IUCN(国际自然保护联盟)的评估,鸟类的保护等级。
love_number = models.IntegerField() # 人气值
observations_number = models.IntegerField() # 观察数
date = models.DateField(auto_now_add=True, verbose_name='添加时间')
class Meta:
verbose_name = '鸟类数据'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
在应用observations中的models.py中编写实体观察的数据模型代码:
class Observation(models.Model):
id = models.AutoField(primary_key=True)
date = models.DateTimeField(auto_now=True, verbose_name='观察时间')
location = models.CharField(verbose_name='观察地点', max_length=255)
description = models.TextField(verbose_name='观察现象')
additional_notes = models.TextField(verbose_name='备注信息', blank=True, null=True)
observation_data = models.CharField(verbose_name='观察数据', max_length=255)
tags = models.CharField(verbose_name='预测结果', max_length=255, blank=True)
bird = models.ForeignKey(Bird, on_delete=models.CASCADE, blank=True, null=True)
class Meta:
verbose_name = '观察数据'
verbose_name_plural = verbose_name
三、 模糊查询搜索功能:
1.路由层:
path('search/', search, name='search')
2.搜索框(前端):
<form action="{% url 'birds:search' %}" style="padding-left: 900px ;margin-top: 10px;margin-bottom: 5px" method="get">
<input type="text" name='text' id="searchInput" placeholder="输入搜索内容...">
<input type="submit" value="搜索">
</form>
3.views层:
def search(reqeust):
text = reqeust.GET.get('text')
res = Bird.objects.filter(Q(name__icontains=text) | Q(order__icontains=text) | Q(family__icontains=text)
| Q(size__icontains=text) | Q(plumage__icontains=text) | Q(habitat__icontains=text)
| Q(distribution__icontains=text) | Q(iucn_status__contains=text))
context = {'res': res}
return render(reqeust, 'birds/search_result.html', context)
4.查询结果(前端):
<tbody>
{% for r in res %}
<tr>
<th>{{ r.id}}</th>
<th><img width="100" height="100" src="{% static r.images %}"/></th>
<th>{{ r.name}}</th>
<th>{{ r.order}}</th>
<th>{{ r.family}}</th>
<th>{{ r.genus}}</th>
<th>{{ r.size}}</th>
<th>{{ r.plumage}}</th>
<th>{{ r.habitat}}</th>
<th>{{ r.distribution}}</th>
<th>{{ r.iucn_status}}</th>
<th>{{ r.love_number}}</th>
<th>{{ r.observations_number}}</th>
<th>{{ r.date}}</th>
</tr>
{% endfor %}
</tbody>
四、 喜欢功能:
1.路由层:
path('love/<int:id>/<str:tags>/', love, name='love'),
path('nolove/<int:id>/<str:tags>/', nolove, name='nolove'),
2.views层:
def love(request, id, tags):
user_id = request.session.get('user_id')
observations = Observation.objects.filter(id=id).first()
user = UserInfo.objects.filter(user_id=user_id).first()
user.love.add(observations)
Bird.objects.filter(id=observations.bird_id).update(love_number=F('love_number') + 1)
return redirect('/observations/knowledge/' + str(id) + '/' + str(tags) + '/')
def nolove(request, id, tags):
user_id = request.session.get('user_id')
observations = Observation.objects.filter(id=id).first()
user = UserInfo.objects.filter(user_id=user_id).first()
user.love.remove(observations)
Bird.objects.filter(id=observations.bird_id).update(love_number=F('love_number') - 1)
return redirect('/observations/knowledge/' + str(id) + '/' + str(tags) + '/')
3.前端代码:
{% if love %}
<th>
<a href="{% url 'observations:nolove' id tags%}">
<span style="font-size: 30px">💔</span>
</a>
</th>
{% else %}
<th>
<a href="{% url 'observations:love' id tags%}" >
<span style="font-size: 30px">💕</span>
</a>
<br>
</th>
{% endif %}
五、总结:
F 对象用于在数据库查询中进行字段之间的比较和操作,它允许在查询中使用字段的值进行计算和比较,而无需将数据提取到 Python 中进行处理,这对于处理大量数据和优化查询非常有用。
Q 对象则用于在获取查询结果集时,使用复杂的逻辑或、逻辑与、逻辑非等操作,当涉及一个或多个查询条件时可以使用 Q 对象进行操作。
由于项目中的表关系比较复杂,本博客不再过度赘述,望大家见谅;博客只是给大家分享一种使用F对象和Q对象实现“模糊查询搜索”与“喜欢”功能的方法。