Filter multiple fields using single input - python

My backend in Python :
def resview(request, *args, **kwargs):
if 'uid' not in kwargs:
kwargs = kwargs.copy()
kwargs['filter'] = {}
username = request.GET.get('username')
if username:
kwargs['filter']['user__username__contains'] = username
return resource_view(request, UserProfile, get_userprof, put_userprof,
deleter=del_userprof, api=request.api, order_by='user__username', **kwargs)
I can successfully search for the username but I want to be able to search on multiple fields with a single input and I don't know how to do it.

I have once in similar situation used Regular Expression to search based on keywords & then pulling out entire line until newline. Here I'm mentioning my small code.
Step1: Save the content in Text file
str = open('file.txt', 'r').read()
import re
#to print id
m = re.search('(?<=id: )(.*)', str)
print ("id= " , (m.groups()))
#to print username
m = re.search('(?<=username: )(.*)', str)
print (username= " , (m.groups()))
############
#and so on----Replace keywords whatever you need...
#############

Considering you're using django, I would suggest to take look at SearchFilter which supports searching multiple fields at once.
Beside of that, you can filter queryset by hands with custom implementation of Filter:
class F(django_filters.FilterSet):
username = CharFilter(method='my_custom_filter')
class Meta:
model = User
fields = ['username', 'firstname', 'lastname', 'email']
def my_custom_filter(self, queryset, name, value):
return queryset.filter(
Q(username__ilike=value)
| Q(firstname__ilike=value)
| Q(lastname__ilike=value)
| Q(email__ilike=value)
)

You can store the JSON list in a list variable and filter the results.
filterData(searchString){
searchString = searchString.trim();
return this.data.filter(user=> user.username.toLowerCase().indexOf(searchString.toLowerCase()) !== -1 || user.firstname.toLowerCase().indexOf(searchString.toLowerCase()) !== -1 || user.lastname.toLowerCase().indexOf(searchString.toLowerCase()) !== -1);
}
I suggest that you use two different lists to save data. One filtered and the other un filtered. This way you won't have to call the service again to get original data. Filter is always applied on unfiltered data.

Related

Q: Simple-Salesforce make a dynamic soql query

Was trying to figure out a way to get simple salesforce to just give me all the field names in a list. I want to create soql query that pretty much does the same thing as a Select * does in sql.
for obj in objects:
fields = [x["name"] for x in sf[obj].describe()["fields"]]
thanks
A list of field names in an object can be achieved as follow:
def getObjectFields(obj):
fields = getattr(sf,obj).describe()['fields']
flist = [i['name'] for i in fields]
return flist
getObjectFields('Contact')
Your query to get the effect of SELECT * would then look something like this:
sf.query_all('SELECT {} FROM Contact LIMIT 10'.format(','.join(getObjectFields('Contact'))))
On a related note:
In case it is helpful, a dictionary of label/name pairs can be achieved as follows:
def getObjectFieldsDict(obj):
fields = getattr(sf,obj).describe()['fields']
fdict = {}
for i in fields:
fdict[i['label']] = i['name']
return fdict
getObjectFieldsDict('Contact')
I find this can be useful for figuring out the names of fields with labels that do not follow the standard format (i.e. "My Favorite Website" field label for "Favorite_Website__c" field name)
This method will return a query string with all fields for the object passed in. Well all the fields the user has access to.
public static string getFullObjectQuery(String sObjectName){
Schema.SObjectType convertType = Schema.getGlobalDescribe().get(sObjectName);
Map<String,Schema.sObjectField> fieldMap = convertType.getDescribe().Fields.getMap();
Set<String> fields = fieldMap.keySet();
String Query = 'SELECT ';
for(String field: fields){
Schema.DescribeFieldResult dfr = fieldMap.get(field).getDescribe();
if(dfr.isAccessible()){
Query += field + ',';
}
}
Query = query.SubString(0,Query.length() - 1);
Query += ' FROM ' + sObjectName;
return Query;
}
#!/usr/bin/env python3
import argparse
import os
import simple_salesforce
parser = argparse.ArgumentParser()
parser.add_argument('--sandbox', action='store_true',
help='Use a sandbox')
parser.add_argument('sfobject', nargs='+', action='store',
help=('Salesforce object to query (e.g. Contact)'))
args = parser.parse_args()
sf = simple_salesforce.Salesforce(
username = os.getenv('USERNAME'),
password = os.getenv('PASSWORD'),
security_token = os.getenv('SECURITY_TOKEN'),
sandbox = args.sandbox)
for sfobject in args.sfobject:
print(sfobject)
fields = [x['name'] for x in getattr(sf, sfobject).describe()['fields']]
print(fields)

Can I lookup a related field using a Q object in the Django ORM?

In Django, can I re-use an existing Q object on multiple models, without writing the same filters twice?
I was thinking about something along the lines of the pseudo-Django code below, but did not find anything relevant in the documentation :
class Author(Model):
name = TextField()
company_name = TextField()
class Book(Model):
author = ForeignKey(Author)
# Create a Q object for the Author model
q_author = Q(company_name="Books & co.")
# Use it to retrieve Book objects
qs = Book.objects.filter(author__matches=q_author)
If that is not possible, can I extend an existing Q object to work on a related field? Pseudo-example :
# q_book == Q(author__company_name="Books & co.")
q_book = q_author.extend("author")
# Use it to retrieve Book objects
qs = Book.objects.filter(q_book)
The only thing I've found that comes close is using a subquery, which is a bit unwieldy :
qs = Book.objects.filter(author__in=Author.objects.filter(q_author))
From what I can tell by your comment, it just looks like you're trying to pass a set of common arguments to multiple filters, to do that you can just unpack a dictionary
The values in the dictionary can still be q objects if required as if it were a value you would pass in to the filter argument normally
args = { 'author__company_name': "Books & co" }
qs = Book.objects.filter(**args)
args['author_name'] = 'Foo'
qs = Book.objects.filter(**args)
To share this between different models, you'd have to do some dictionary mangling
author_args = { k.lstrip('author__'): v for k, v in args.items }
You can do this
books = Book.objects.filter(author__company_name="Books & co")

django-datatables-view load filtered model

Here we have the basic code for getting django-datatables-view to display
from django_datatables_view.base_datatable_view import BaseDatatableView
class OrderListJson(BaseDatatableView):
# The model we're going to show
model = MyModel
# define the columns that will be returned
columns = ['number', 'user', 'state', 'created', 'modified']
# define column names that will be used in sorting
# order is important and should be same as order of columns
# displayed by datatables. For non sortable columns use empty
# value like ''
order_columns = ['number', 'user', 'state', '', '']
# set max limit of records returned, this is used to protect our site if someone tries to attack our site
# and make it return huge amount of data
max_display_length = 500
def render_column(self, row, column):
# We want to render user as a custom column
if column == 'user':
return '{0} {1}'.format(row.customer_firstname, row.customer_lastname)
else:
return super(OrderListJson, self).render_column(row, column)
def filter_queryset(self, qs):
# use parameters passed in GET request to filter queryset
# simple example:
search = self.request.GET.get(u'search[value]', None)
if search:
qs = qs.filter(name__istartswith=search)
# more advanced example using extra parameters
filter_customer = self.request.GET.get(u'customer', None)
if filter_customer:
customer_parts = filter_customer.split(' ')
qs_params = None
for part in customer_parts:
q = Q(customer_firstname__istartswith=part)|Q(customer_lastname__istartswith=part)
qs_params = qs_params | q if qs_params else q
qs = qs.filter(qs_params)
return qs
This code works fine, however, how do I get it to not display the whole model, but only filtered content from the model? I've tried setting it to model = MyModel.objects.filter(name="example") but this returns an error.
def get_initial_queryset(self):
return MyModel.objects.filter(name="example")
Add this in your Class OrderListJson
You can use the get_initial_queryset method that returns the queryset used to populate the datatable.

How to check for blank fields in input json data in python?

Suppose in my python below function, i am getting the json feeds like below
def mapper_1(self, key, line):
j_feed = json.loads(line)
unicoded = j_feed[u'category_description'].encode("utf-8")
cn = j_feed[u'categoryname']
location = j_feed[u'location']
How to check if there is any blank fields for data in categoryname/categorydescription/location from the input.json.
Say you are unsure of your fields, you can use .get and provide it a default sentinel value
fields = ['categoryname', 'categorydescription', 'location']
for field in fields:
print j_feed.get(field, "not set!")

How do I order by date when using ReferenceProperty?

I have a simple one-to-many structure like this:
class User(db.Model):
userEmail = db.StringProperty()
class Comment(db.Model):
user = db.ReferenceProperty(User, collection_name="comments")
comment = db.StringProperty()
date = db.DateTimeProperty()
I fetch a user from by his email:
q = User.all() # prepare User table for querying
q.filter("userEmail =", "az#example.com") # apply filter, email lookup
results = q.fetch(1) # execute the query, apply limit 1
the_user = results[0] # the results is a list of objects, grab the first one
this_users_comments = the_user.comments # get the user's comments
How can I order the user's comments by date, and limit it to 10 comments?
You will want to use the key keyword argument of the built-in sorted function, and use the "date" property as the key:
import operator
sorted_comments = sorted(this_users_comments, key=operator.attrgetter("date"))
# The comments will probably be sorted with earlier comments at the front of the list
# If you want ten most recent, also add the following line:
# sorted_comments.reverse()
ten_comments = sorted_comments[:10]
That query fetches the user. You need to do another query for the comments:
this_users_comments.order('date').limit(10)
for comment in this_users_comments:
...

Categories