简体   繁体   中英

Django searching for a string match in a list of dictionary which is returned from queryset.

I have something like this in my view.py

def calculateMark(mobile_a, mobile_b):
    #variables
    mobile_a = mobile_a
    mobile_b = mobile_b

    results_a = []
    results_b = []
    record_a = TechSpecificationAdd.objects.filter(mobile_name=mobile_a).values()
    record_b = TechSpecificationAdd.objects.filter(mobile_name=mobile_b).values()
    results_a += record_a
    results_b += record_b
    record_a = record_a[0]
    record_b = record_b[0]

    if 'Android' in record_a['os']:
        os_mark_a = 8.9
    elif 'Android' in record_b['os']:
        os_mark_b = 8.9
    elif 'iOS' in record_a['os']:
        os_mark_a = 14
    if 'iOS' in record_b['os']:
        os_mark_b = 14
    else:
        os_mark_a = 1
        os_mark_b = 1

calculateMark Function will calculate a mark for mobiles. Everything is ok but in case of Operating System (os) testing. Its returning always the else block.

The question is how can I search for a string like "ios" in my record['os'] field?

Correct me if I'm wrong, but I believe your problem is the if in the following line:

if 'iOS' in record_b['os']:

As a result of this code in every case other than iOS in record_b , both os_mark_a and os_mark_b will be set to 1 . Even if they were set to another value before, they will be overwritten by 1 . To correct this particular problem change the line to:

elif 'iOS' in record_b['os']:

There are other things I find weird:

  • In most cases you set just one of os_mark_b or os_mark_a , leaving the other one unset. You could correct this for example by settings both to a default value first.

  • You don't need to load the values to a dictionary using values() - just use .get() and use the resulting object directly. Among other benefits this would eliminate lines 6, 7, 10, 11, 12, 13 completely.

  • Calculations for A and B seem completely separate. It seems it would be wiser to create a smaller method that calucaltes mark for a single object.

  • Your method doesn't return anything. I presume that's only because it's a simplified example.

  • What's the following code is about? That doesn't do anything...

     mobile_a = mobile_a mobile_b = mobile_b 

Update: Example of code without those issues:

def calculateMark(mobile):
    record = TechSpecificationAdd.objects.get(mobile_name=mobile)

    if 'Android' in record.os:
        return 8.9
    if 'iOS' in record.os:
        return 14
    return 1

Update 2: Also, since we already got so far in making this code better - this shouldn't be a separate function, but a method on a TechSpecificationAdd object.

class TechSpecificationAdd(models.Model):
    # some fields

    def calculateMark(self):
        if 'Android' in self.os:
            return 8.9
        if 'iOS' in self.os:
            return 14
        return 1

You would then use this in your code like this:

record = TechSpecificationAdd.objects.get(mobile_name=mobile)
mark = record.calculateMark()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM