I'm trying to filter API responses through a web search. After typing a search query it doesn't filter the result. I'm also using pagination. How to solve this do I need to make changes in my filter or View.
search query
http://127.0.0.1:8000/course-api/subjectlist/?search="ICT"/
after giving this search query still it returns all of the elements through the response.
Subject model
class Subject(models.Model):
def upload_location(instance, filename):
return "subject_images/%s/%s" % (instance.subject_name, filename)
subject_name = models.CharField(max_length=200, null=True)
subject_cover = models.ImageField(null=True, blank=True, upload_to=upload_location,default="subject_images/default.png")
description = models.CharField(max_length=500, null=True, blank=True)
author = models.ForeignKey(TeacherProfile,on_delete=models.CASCADE,null=True,default=None)
subject_type = models.CharField(max_length=100, null=True, blank=True)
class_type = models.CharField(max_length=10, null=True, blank=True)
short_description = models.CharField(max_length=300,blank=True,null=True)
created_at = models.DateTimeField(default=now)
filters.py
import django_filters
from ..models import Subject
class SubjectFilter(django_filters.FilterSet):
class Meta:
model = Subject
fields = ['subject_name']
Views.py
#api_view(['GET'])
def SubjectList(request):
paginator = PageNumberPagination()
paginator.page_size=5
subjects =SubjectFilter ( request.GET, queryset= Subject.objects.all())
result_page = paginator.paginate_queryset(subjects.queryset,request)
serializer = SubjectViewSerializer(result_page,many=True)
return paginator.get_paginated_response(serializer.data)
Related
I have 3 models and I am trying to create a dashboard with a list of Trials that spans all Client Sessions for a specific client chosen via a filter.
Here are the models:
class Trial(models.Model):
behavior_name = models.ForeignKey(Behavior, on_delete=models.CASCADE)
client_session = models.ForeignKey(Client_Session, on_delete=models.CASCADE)
frequency_input = models.PositiveIntegerField(default=0, blank=True)
duration_input = models.DurationField(blank=True, default=timedelta(minutes=0))
class Meta:
verbose_name_plural = 'trials'
def __str__(self):
return str(self.id)
class Client_Session(models.Model):
name = models.CharField(max_length=200, null=False)
session_date = models.DateField(blank=False,null=False)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
behaviors = models.ManyToManyField(Behavior, null=False)
therapist = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
class Meta:
verbose_name_plural = 'clientsessions'
def __str__(self):
return self.name
class Client(models.Model):
#user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
date_of_birth = models.DateField(blank=True, null=True)
gender = models.CharField(max_length=10, choices=GENDER_CHOICES,blank=True)
gaurdian_first_name = models.CharField(max_length=200, blank=True)
gaurdian_last_name = models.CharField(max_length=200, blank=True)
diagnosis = models.CharField(max_length=200, choices=DIAGNOSIS_CHOICES, blank=True)
therapist = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
def __str__(self):
return self.last_name
Here is the view that im trying to create
def dashboard(request):
# filter list of client sessions by selected client
client_sessions = Client_Session.objects.filter(therapist=request.user)
client = DashboardClientFilter(request.GET, queryset=client_sessions)
client_sessions = client.qs
#Create list of Trials across Client Sessions for the filtered client
trial_list = Trial.objects.filter(client_session__client=client)
You have an error filter query you used Filter data. Expected is queryset.
Change,
trial_list = Trial.objects.filter(client_session__client=client)
into
client_sessions = client.qs
client_pks = client.qs.values_list('client_id',flat=True)
trial_list = Trial.objects.filter(client_session__client_id__in= list(client_pks))
trial_list = Trial.objects.filter(client_session__client__in= list(client_pks)).distinct() distinct() method is used to remove duplicated but it not work some databases
I am work on a Django Project where I have Profile and submited_apps models. The profile model holds details such as applicant, nation, state, phone etc whereas the submited_apps models only records the users whose application were submitted successfully with a applicant field, Universal Unique International Id and date.
How do I have a dependent search form for nation and state and be able to search submited_apps model for selected nation, state and display the result in pagination.
Profile Model Code below
class Profile(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=10, null=True)
othernames = models.CharField(max_length=30, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
nation = models.CharField(max_length=10, choices=NATION, blank=True, null=True)
state = models.CharField(max_length=20, null=True)
address = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=11, null=True)
image = models.ImageField(default='avatar.jpg', upload_to ='profile_images')
Submitted Model Code below"
class submited_apps(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
application = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
confirm = models.BooleanField()
date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.application == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.applicant
def __str__(self):
return f'Application Number: {self.application}-{self.applicant}'
ModelForm code below:
class Applicant_Search_Form(forms.ModelForm):
class Meta:
model = submited_apps
fields = ['applicant']
Here is my view for the search
def SearchApplicants(request):
context = {}
searchForm = Applicant_Search_Form(request.POST or None)
if searchForm:
list_applicants = submited_apps.objects.filter(applicant__iexact=[searchForm['applicant'].value()])
else:
list_applicants= submited_apps.objects.all()
paginator = Paginator(list_applicants, 5)
page = request.GET.get('page')
paged_listApps = paginator.get_page(page)
context.update({
'list_applicants':paged_listApps,
'searchForm':searchForm,
})
return render(request, 'user/search_applicants_nation.html',context)
My problem is that I am getting this error message upon load of the plage.
Related Field got invalid lookup: icontains
I have this models on django with natural_keys functions declared.
class Comments(models.Model):
profile = models.ForeignKey('Profiles', models.DO_NOTHING)
book = models.ForeignKey(Books, models.DO_NOTHING)
date = models.DateTimeField()
text = models.TextField()
class Meta:
managed = False
db_table = 'comments'
class Profiles(models.Model):
alias = models.CharField(max_length=40)
mail = models.CharField(max_length=255)
mainimg = models.ForeignKey(Multimedia, models.DO_NOTHING)
birthdate = models.DateTimeField(blank=True, null=True)
country = models.CharField(max_length=30, blank=True, null=True)
password = models.CharField(max_length=255)
terms = models.IntegerField(blank=True, null=True)
device_token = models.CharField(max_length=500)
def natural_key(self):
return (self.pk, self.alias, self.country, self.mainimg)
class Meta:
managed = False
db_table = 'profiles'
class Multimedia(models.Model):
url = models.CharField(max_length=255)
title = models.CharField(max_length=100)
alt = models.CharField(max_length=150, blank=True, null=True)
description = models.CharField(max_length=150, blank=True, null=True)
mytype = models.CharField(max_length=20, blank=True, null=True)
extension = models.CharField(max_length=6, blank=True, null=True)
def natural_key(self):
return (self.pk, self.url)
class Meta:
managed = False
db_table = 'multimedia'
When I do a get comments query, I want a full response with the comment details, some book details, and profile details (including the picture). Everything goes fine except when I want the profile mainimg being serialized with natural keys.
The error response is
is not JSON serializable
when executing this:
def getcomments(request):
#Book get all comments - returns all comments on a book.
profilelogged = validtoken(request.META['HTTP_MYAUTH'])
if not profilelogged:
return HttpResponse('Unauthorized', status=401)
else:
index = request.GET.get('id', 0)
bookselected = Books.objects.filter(pk=index).first()
comments = list(Comments.objects.filter(book=bookselected).order_by('-date').all())
books_json = serializers.serialize('json', comments, use_natural_foreign_keys=True)
return HttpResponse(books_json, content_type='application/json')
Anyway I can get multimedia url on comment query on same response object serialized?
Thanks.
You are trying to convert ForeignKey object into JSON object which gives error as ForeignKey contains serialized data,
So you have to use safe parameter to convert your data into JSON.
return HttpResponse(books_json, content_type='application/json', safe=False)
if it doesn't work! Try this:
return HttpResponse(books_json, safe=False)
Otherwise you can always user JsonResponse as it is safer to user for propagation of JSON objects.
P.S:
Why your Profile ForeignKey in first Model is in quotes? Is it on purpose?
Thanks everyone.
I have reached what i want adding to the Profiles model natural_key function the Multimedia fields I want to use, insted of the full Multimedia model I do not need.
class Profiles(models.Model):
alias = models.CharField(max_length=40)
mail = models.CharField(max_length=255)
mainimg = models.ForeignKey(Multimedia, models.DO_NOTHING)
birthdate = models.DateTimeField(blank=True, null=True)
country = models.CharField(max_length=30, blank=True, null=True)
password = models.CharField(max_length=255)
terms = models.IntegerField(blank=True, null=True)
device_token = models.CharField(max_length=500)
def natural_key(self):
return (self.pk, self.alias, self.country, self.mainimg.pk, self.mainimg.url)
class Meta:
managed = False
db_table = 'profiles'
And now, the reponse is what I wanted.
Models:
class Applicant_Skill(models.Model):
user = models.ForeignKey(User)
#applicant = models.ForeignKey(Applicant)
skill = models.ForeignKey('skills_layer.Skill')
active = models.BooleanField(default=True)
class Job_Posting(models.Model):
company = models.ForeignKey('companies_layer.Company', default=-1)
job_posted_by = models.ForeignKey(User, default=-1)
job_title = models.CharField(max_length=100)
job_summary = HTMLField(blank=True)
job_details = HTMLField(blank=True)
no_of_openings = models.IntegerField(default=0)
tags = models.CharField(max_length=200)
experience_min = models.IntegerField(default=0)
experience_max = models.IntegerField(default=0)
job_location = models.ForeignKey('meta_data_layer.Location', blank=True, null=True)
qualification = models.ForeignKey('meta_data_layer.Qualification', default=-1)
specialization = models.ForeignKey('meta_data_layer.Specialization', default=-1)
nationality = models.ForeignKey('meta_data_layer.Nationality', default=-1)
live = models.BooleanField(default=True)
closing_date = models.DateField(default=datetime.date.today())
auto_renew = models.BooleanField(default=False)
active = models.BooleanField(default=True)
class Meta:
verbose_name = "job posting"
def __str__(self):
return self.job_title
Resource:
from tastypie.resources import ModelResource
from job_posting_layer.models import Job_Posting
from companies_layer.models import Company
from django.contrib.auth.models import User
import meta_data_layer
from tastypie import fields
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
def dehydrate(self, bundle):
bundle.data['logged_user_id'] = bundle.request.user.id
return bundle
class JobListingResource(ModelResource):
#company = fields.ForeignKey(CompanyResource,'company', full=True)
#job_posted_by = fields.ForeignKey(UserResource,'job_posted_by', full=True)
company_name = fields.CharField(attribute="company__company_name", null=True)
company_id = fields.CharField(attribute="company__id", null=True)
user_first_name = fields.CharField(attribute="job_posted_by__first_name", null=True)
user_last_name = fields.CharField(attribute="job_posted_by__last_name", null=True)
user_id = fields.CharField(attribute="job_posted_by__id", null=True)
job_location = fields.CharField(attribute="job_location__location_name", null=True)
job_city = fields.CharField(attribute="job_location__city", null=True)
qualification = fields.CharField(attribute="qualification__qualification_degree", null=True)
specialization = fields.CharField(attribute="specialization__specialization_course", null=True)
nationality = fields.CharField(attribute="nationality__country_name", null=True)
class Meta:
queryset = Job_Posting.objects.all()
resource_name = 'jobs'
Today is the 1st day I am trying Tastypie so please be kind with me :(
The JobListingResource returns all the Job Listings. But I want to get only those Job Listings for which the Tags column contains values from the skill column of the logged in user.
Eg: If user "A" has logged in and has the following skills "python,django,jquery". I want the JobListingResource to return only those records which contains [python/django/jquery] in the tags column.
I'm assuming you know how to do the queries and just need to know where to do it in Tastypie. In your JobListResource override as follows:
def get_object_list(self, request):
# get all the jobs according to the queryset in Meta
base = super(JobListingResource, self).get_object_list(request)
# and add a filter so only users ones appear
user = request.user
skills = query to get all the skills for the user
return base.filter(filter to apply to JobPosting to only return jobs matching skills list)
I have a Django 'add business' view which adds a new business with an inline 'business_contact' form.
The form works fine, but I'm wondering how to write up the unit test - specifically, the 'postdata' to send to self.client.post(settings.BUSINESS_ADD_URL, postdata)
I've inspected the fields in my browser and tried adding post data with corresponding names, but I still get a 'ManagementForm data is missing or has been tampered with' error when run.
Anyone know of any resources for figuring out how to post inline data?
Relevant models, views & forms below if it helps. Lotsa thanks.
MODEL:
class Contact(models.Model):
""" Contact details for the representatives of each business """
first_name = models.CharField(max_length=200)
surname = models.CharField(max_length=200)
business = models.ForeignKey('Business')
slug = models.SlugField(max_length=150, unique=True, help_text=settings.SLUG_HELPER_TEXT)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
phone = models.CharField(max_length=100, null=True, blank=True)
mobile_phone = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(null=True)
deleted = models.BooleanField(default=False)
class Meta:
db_table='business_contact'
def __unicode__(self):
return '%s %s' % (self.first_name, self.surname)
#models.permalink
def get_absolute_url(self):
return('business_contact', (), {'contact_slug': self.slug })
class Business(models.Model):
""" The business clients who you are selling products/services to """
business = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=100, unique=True, help_text=settings.SLUG_HELPER_TEXT)
description = models.TextField(null=True, blank=True)
primary_contact = models.ForeignKey('Contact', null=True, blank=True, related_name='primary_contact')
business_type = models.ForeignKey('BusinessType')
deleted = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
address_1 = models.CharField(max_length=255, null=True, blank=True)
address_2 = models.CharField(max_length=255, null=True, blank=True)
suburb = models.CharField(max_length=255, null=True, blank=True)
city = models.CharField(max_length=255, null=True, blank=True)
state = models.CharField(max_length=255, null=True, blank=True)
country = models.CharField(max_length=255, null=True, blank=True)
phone = models.CharField(max_length=40, null=True, blank=True)
website = models.URLField(null=True, blank=True)
class Meta:
db_table = 'business'
def __unicode__(self):
return self.business
def get_absolute_url(self):
return '%s%s/' % (settings.BUSINESS_URL, self.slug)
VIEWS:
def business_add(request):
template_name = 'business/business_add.html'
if request.method == 'POST':
form = AddBusinessForm(request.POST)
if form.is_valid():
business = form.save(commit=False)
contact_formset = AddBusinessFormSet(request.POST, instance=business)
if contact_formset.is_valid():
business.save()
contact_formset.save()
contact = Contact.objects.get(id=business.id)
business.primary_contact = contact
business.save()
#return HttpResponse(help(contact))
#business.primary = contact.id
return HttpResponseRedirect(settings.BUSINESS_URL)
else:
contact_formset = AddBusinessFormSet(request.POST)
else:
form = AddBusinessForm()
contact_formset = AddBusinessFormSet(instance=Business())
return render_to_response(
template_name,
{
'form': form,
'contact_formset': contact_formset,
},
context_instance=RequestContext(request)
)
FORMS:
class AddBusinessForm(ModelForm):
class Meta:
model = Business
exclude = ['deleted','primary_contact',]
class ContactForm(ModelForm):
class Meta:
model = Contact
exclude = ['deleted',]
AddBusinessFormSet = inlineformset_factory(Business,
Contact,
can_delete=False,
extra=1,
form=AddBusinessForm,
)
The problem is you have not included the management form in your data. You need to include form-TOTAL_FORMS (total number of forms in the formset, default is 2), form-INITIAL_FORMS (the initial number of forms in the formset, default is 0) and form-MAX_NUM_FORMS (the maximum number of forms in the formset, default is '').
See the Formset documentation for more information on the management form.