Wednesday, 15 April 2015

Django/Python DRY: how to avoid repeat code when working with Q objects and model attributes -


I am trying to create a search page which will allow a user to find any instance of a model that Some thresholds meet the criteria and there is a problem to avoid the redundant code seriously. I hope that there is a better way to do this. Here's a little complied example, which tells me what I'm trying to do, with the corresponding code adjusted at the end. The user will interact with the search with the checkbox. class ice-cream (models.Model ()): name = models.CharField () bad_threshold = models.IntegerField () okay_threshold = models. IntegerField () Tasty_threshold = models.IntegerField () delicious_threshold = models.IntegerField ()

views.py:

  DEF Search_iscams (request): user = request Kuser q_search = does not, 'taste_search in request.GET': q_search = taste_threshold_set (request, user, q_search) If q_search no ==: icecream_list = Icecream.objects.order_by ( 'name') and: Icecream_list = College.objects. Filter (q_search) context = {'icecream_list': icecream_list} return render (request, '/icecream/icecreamsearch.html', context)   

The relevant code that I want to cut As follows, it is much more straightforward than my project, with the name change.

  def taste_threshold_set (request, user, q_search): border = request.GET.getlist ( 'taste_search') user_type_tolerance = user.profile.get_tolerance_of (ICEA # 1-5 are different thresholds.. they are abbreviated to cut # length of the URL in the range '1': new_q = Q (bad_threshold__gt = user.profile.taste_tolerance) If q_search no ==: q_search = new_q rest: q_search = (q_search) | (new_q) if the "2" range: new_q = Q (bad_threshold__lte = user.profile.taste_tolerance) & amp; \ ~ Q (okay_threshold__lte = user.profile.taste_tolerance) If q_search no ==: q_search = new_q rest: q_search = (Q_search) | (new_q) if '3' c The test: new_q = Q (okay_threshold_3__lte = user.profile.taste_tolerance) & amp; \ ~ Q (tasty_threshold__lte = user.profile.taste_tolerance) If q_search no ==: q_search = new_q rest: Q_search = (q_search) | (new_q ) If '4' in range: new_q = Q (tasty_threshold__lte = user.profile.taste_tolerance) and q Lerance) if q_search == none: q_search = new_q other: q_search = (q_search) | (New_q) if '5' in threshold: new_q = Q (delicious_threshold__lte = user.profile.taste_tolerance) if q_search == none: q_search = new_q other: q_search = (q_search) | (New_q) returns q_search   

Actually I want the user to be able to find all the instances of a certain object that meets a given threshold level. Therefore, for example, all the ice creams that they will get spoiled and all the ice cream they will find delicious.

There are many things that I am not happy about this code. I do not like to check to see that the Q object is not yet installed for every potential threshold, but there is no way around it. Apart from this, if it was a non-DNS problem, then instead of writing each one I would use a loop to check each of the given thresholds but again, I'm not sure how to do this.

Finally, the biggest problem is, I have to check the threshold for perhaps 20 different attributes of the model. Since it stands, I have to write a new threshold checker for every one, which will be slightly different from each other (the name of the attribute which is checking). I like being able to write a generic checker, then to pass it to the specific attribute, or is there any way to solve my other two problems?

Thank you!

How?

  query_arg = [ 'bad_threshold__lte', 'bad_threshold__lte', 'okay_threshold_3__lte', 'tasty_threshold__lte', 'delicious_threshold__lte'] Q (** {query_arg [integer (range of this approach) - 1]: user.profile.taste_tolerance})    

No comments:

Post a Comment