根据 Django 国家/地区字段过滤查询集

Posted

技术标签:

【中文标题】根据 Django 国家/地区字段过滤查询集【英文标题】:filter queryset based on django countries field 【发布时间】:2020-12-19 12:49:53 【问题描述】:

这是我的观点:

class PollViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Poll.objects.all()
    serializer_class = PollSerializer()

    def get_queryset(self):
        country = self.kwargs.get('pk', None)
        if country is not None:
            django_countries.Countries.name(country)
            return self.queryset.filter(personality__country__name=country)
        else:
            country = self.request.user.preferred_country
            return self.queryset.filter(personality__country=country)

模型.py:

from django_countries.fields import CountryField



    class Personality(models.Model):
        name = models.CharField(max_length=100)
        bio = models.TextField()
        age = models.IntegerField()
    
        class Gender(models.TextChoices):
            MALE = 'MALE', _('Male')
            FEMALE = 'FEMALE', _('Female')
            OTHER = 'OTHER', _('Other')
    
        gender = models.CharField(
            max_length=6,
            choices=Gender.choices,
            default=Gender.MALE,
        )
    
        country = CountryField(null=True)
        picture = models.ImageField(upload_to='uploads/profile_images/%Y/%m/%d')
    
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return self.name



    class Poll(RulesModel):
        personality = models.OneToOneField(Personality, related_name='polls', on_delete=models.CASCADE)
        start_date = models.DateTimeField(null=True)
        end_date = models.DateTimeField(null=True)
    
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return 'poll#' + str(self.id) + ' ' + self.personality.name

网址.py

from django.conf.urls.static import static
from django.urls import path, include

from liderate import settings
from .views import PollViewSet, PersonalityViewSet, PollListViewSet

from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'polls', PollViewSet)
router.register(r'polls-list', PollListViewSet)
router.register(r'personalities', PersonalityViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

这里会引发异常“不支持为 CountryField 查找 'name' 或加入不允许的字段。”

这是在 if 条件下提出的(else 条件工作得很好)。有没有其他方法可以根据国家名称过滤查询集

我实际上只想查看在获取 URL 中作为参数传递的与国家相关的民意调查

【问题讨论】:

您能添加Personality 型号吗.. 只是为了检查country 字段 请贴出相关代码,urls.pyPersonality模型是怎么定义的? 我添加了个性模型和urls.py 【参考方案1】:

我在基于 CountryField 的项目模型中有一个名为 location_countries 的字段。这是一个多选,我需要根据国家名称或项目其他字段中可用的任何其他信息创建搜索。传统方法,例如“filter(fieldname__icontains) 或 Q(fieldname__country__name) 等失败了。经过大量的麻烦、搜索和思考,我终于设计了一个按我的意图工作的解决方法。现在通过在我的搜索字段它返回基于“美属萨摩亚”或“阿富汗”的所有项目,并返回所有基于“阿富汗”的项目。希望这也对你有帮助。在名为“searchTxt”的普通 html 输入标签中搜索字段。避免重复我首先将结果转换为设置,然后返回列表。

    def viewProjects(request):
        if request.user.is_authenticated:
            if 'searchTxt'  in  request.GET:
                qry = request.GET['searchTxt']
        
            countries_list = []
            pros = Project.objects.all()
                for pro in pros:
            
                    for i in pro.location_countries:
                        if qry.lower() in i.name.lower():                       
                            countries_list.append(pro.project_heading)

        
            res=Project.objects.filter(project_heading__in=countries_list)
        
            projs = Project.objects.filter(                                                 
                                            Q(project_id__icontains=qry)|                                           
                                            Q(project_heading__icontains=qry) |
                                            Q(project_description__icontains=qry)|
                                            Q(sla_type__icontains=qry)|
                                            Q(project_type__icontains=qry)|
                                            Q(project_priority__icontains=qry)|
                                            Q(location_countries__exact=qry)|                                       
                                            Q(location_cities__icontains=qry)|                                      
                                            Q(project_manager__username__icontains=qry)|                                        
                                            Q(escalation_manager__username__icontains=qry)                                      
                                        )

        
        
            project = list(chain(res, projs))
            prj = set(project)
            projects=list(prj)
           
            context =  'projects':projects 
            return render(request, 'admin_view_projects.html', context)
        else:   
            projects = Project.objects.all()
        
            context =  'projects':projects 
            return render(request, 'admin_view_projects.html', context)
    else:
        return redirect('index')

【讨论】:

以上是关于根据 Django 国家/地区字段过滤查询集的主要内容,如果未能解决你的问题,请参考以下文章

Django如何过滤多对多字段中的对象,而不是原始查询集

Django 查询集过滤,将字段与字段进行比较

如果字段存在,Django过滤查询集

Django 查询集过滤器文件字段不为空

构建请求 URL 以通过同一字段多次过滤 Django 查询集

如何按非字段值过滤 Django 查询集