We can see this writeup when querying the database using Django's models:
form import XXX query = () query = (name=123, age=456).filter(salary=999)
Inside this writeup, the query object has afilter
method, the return data from this method can also continue to call thefilter
method, which can be called on indefinitely in this way.
How is this writeup achieved?
If we write a class method directly, let's see if we can call it that way:
class Query: def filter(self): pass query = Query() ().filter()
direct-to-()
The returned result is called againfilter
This is because the method will return an error if no return statement is explicitly written. This is because when the return statement is not explicitly written, the method will returnNone
and None objects are not calledfilter
Methodology.
So what has a filter method? Obviously our query object has a filter method. So how do we get this method to return itself as an object?
At this point, we need to look at the first parameter we always write when defining class methodsself
up. It's inside almost every class method. All people know is that you can call a class method from inside a class with the()
, when calling class attributes you can use the, so has there been any thinking about what would happen to this thing if it was used on its own?
In fact.self
It refers to the object itself after the class is instantiated into an object. And this object obviously hasfilter
method. So let's modify thefilter
method, have it returnself
:
class Query: def filter(self): return self query = Query() ().filter()
As you can see from the image, it doesn't report errors anymore. So back to the very beginning, how is chaining calls inside Django to pass in query parameters implemented?
There is actually aInert queries
of the problem.
When we keep calling.filter()
method, Django will cache all these query conditions, and only when we need to get the results, or query how many pieces of data satisfy the conditions, it will actually connect to the database to query.
So we're going to simulate that environment here by caching the query conditions.
Then in order to get the name of the parameter passed in when the method is called, we have to use the**kwargs
Parameter. This parameter accepts all arguments of the form key=value:
class Query(): def __init__(self): self.query_condition = {} def filter(self, **kwargs): self.query_condition.update(kwargs) return self query = Query() a = (name='kingname').filter(age__gt=15, address='yyyyyy').filter(salary=99999) print(query.query_condition)
The running effect is shown below:
When you really need to output the results, you can then use these cached conditions to go to the database and query the results.
Above is how to achieve chained calls in python in detail, more information about python to achieve chained calls please pay attention to my other related articles!