The filters parameter that we want to add to the use case would allow the caller to add conditions with which the user would be able to narrow the results of the model list operation. The caller would do this by using a notation like <attribute>__<operator>. For example, specifying filters={'price__lt': 100} should return all the results with a price less than 100.

Since the Room model has many attributes, the number of possible filters is very high. For simplicity’s sake, we’ll consider the following cases:

  • The attribute code supports only __eq, which finds the room with the specified code if it exists.
  • The attribute price supports __eq, __lt, and __gt.
  • No other attributes can be used in the filters.

The core idea here is that requests are customized for use cases, so they can contain the logic that validates the arguments used to instantiate them. The request is valid or invalid before it reaches the use case. So, it isn’t the responsibility of the latter to check if the input values have proper values or a proper format. This also means that building a request may result in two different objects: one valid and one invalid. For this reason, we’ll split the existing RoomListRequest class into RoomListValidRequest and RoomListInvalidRequest. This creates a factory function that returns the proper object.

Update test case for no filters

The first thing to do is to change the existing tests so they may use the factory. This is done in the code below:

Get hands-on with 1200+ tech skills courses.