Reputation: 11
this is my viewset:
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)
model.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
Urls.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)),
]
here it raises exception that "Unsupported lookup 'name' for CountryField or join on the field not permitted."
this is raised in the if condition (else condition works perfectly fine). is there any other way of filtering the query set based on the country's name
i actually want to view only the polls related to country passed as a param in the get url
Upvotes: 1
Views: 1328
Reputation: 27
I had a field named location_countries in my project model based on CountryField. It was a multiselect and I needed to create a search based on country name or any other information available in project's other fields. conventional ways e.g "filter(fieldname__icontains) or Q(fieldname__country__name) etc failed. After a lot of trouble, search and thinking, I finally devised a workaround that is working as I intended. Now by giving any keywords for example "samo" in my search field it returns all projects based in "American Samoa" or "afghan" and it retruns all projects based in "Afghanistan". Hope This helps you also. Search field in normal html input tag named "searchTxt". to avoid duplication i first converted result to set and then back to list.
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')
Upvotes: 0