Home > Software design >  Comparing two lists with each other and color the difference with django
Comparing two lists with each other and color the difference with django

Time:12-16

I have a django application. And I try to mark the difference values in the lists red in the template.

So I have some methods with lists inside. Because in the real situation. You can upload a pdf and excel file. But this is just for testing. So that I can use it in the real situation. But the idea is the same.

So this are the methods:

from django.utils.safestring import mark_safe
from tabulate import tabulate

class FilterText:
def total_cost_fruit(self):
        return [3588.20, 5018.75, 3488.16]

    def show_extracted_data_from_file(self):       

        regexes = [self.total_cost_fruit()]
        matches = [(regex) for regex in regexes]
        columns = ["kosten fruit"]

        return mark_safe(
            tabulate(
                zip_longest(*matches),  # type: ignore
                headers=columns,
                tablefmt="html",
                stralign="center",
            )
        )

and second class:

from django.utils.safestring import mark_safe
from tabulate import tabulate

class ExtractingTextFromExcel:
    def init(self):
        pass

 def extract_data_excel_combined(self):      
        new_fruit_list = [[i] for i in self.total_fruit_cost()]        
        columns = ["totaal", "kosten", "fruit"]
        return mark_safe(tabulate(new_fruit_list, headers=columns, tablefmt="html", stralign="center"))

 def total_fruit_cost(self):
        dict_fruit = {"Watermeloen": 3588.10, "Appel": 5018.40, "Sinaasappel": 3488.16}
        fruit_list = list(dict_fruit.values())  #[[i] for i in dict_fruit.values()]
        print(fruit_list)
        return fruit_list

and the views.py:

def test(request):
    filter_excel = ExtractingTextFromExcel()
    filter_text = FilterText()
    compare_data = CompareData()
    total_fruit_cost_pdf = filter_text.total_cost_fruit()
    total_fruit_cost_excel = filter_excel.total_fruit_cost()
    diff_set = compare_data.diff(total_fruit_cost_pdf, total_fruit_cost_excel)
    
    print(diff_set)

    content_excel = ""
    content_pdf = ""
    content_pdf = filter_text.show_extracted_data_from_file()
    content_excel = filter_excel.extract_data_excel_combined()
    context = {
        "content_pdf": content_pdf,
        "content_excel": content_excel,
        "diff_set": diff_set,
    }

    return render(request, "main/test.html", context)

and template:


<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Create a Profile</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <link rel="stylesheet" type="text/css" href="{% static 'main/css/custom-style.css' %}" />
        <link rel="stylesheet" type="text/css" href="{% static 'main/css/bootstrap.css' %}" />
    </head>

    <body>
        <div >
            <span  role="form">
                <div >
                    <form  action="controlepunt140" method="POST" enctype="multipart/form-data">

                        <div >
                            <div >
                                {% csrf_token %}
                                {{ pdf_form.as_p }}
                            </div>
                            <div >
                                <div >
                                    <div >


                                        {% for value in content_pdf %}
                                        <span {% if value in diff_set %} style="color: red;" {% endif %}>
                                            {{value}}</span>
                                        {% endfor %}

                                    </div>
                                </div>
                            </div>
                        </div>
                </div>
            </span>


            <span  role="form">
                <div >
                    <form  action="controlepunt140" method="POST" enctype="multipart/form-data">

                        <div >
                            <div >
                                {% csrf_token %}
                                {{ excel_form.as_p }}
                            </div>
                            <div >
                                <div >
                                    <div >


                                        {% for value in content_excel %}
                                        <span {% if value in diff_set %} style="color: red;" {% endif %}>
                                            {{value}}</span>
                                        {% endfor %}


                                    </div>
                                </div>
                            </div>
                        </div>
                </div>
            </span>
            <span  role="form">
                <div >
                    <div >
                        <div >

                            </br></br></br></br></br></br></br></br></br>

                            <button type="submit" name="form_pdf" >Upload!</button>
                        </div>
                    </div>
                </div>
            </span>
            </form>
        </div>
    </body>
</html>

So if I do a print statement in the views.py method. Then I see the correct differences:

{5018.75, 3588.2, 3588.1, 5018.4}

But in the template is nothing to see.

Question: how to mark the different values red?

if you do in the template:

<div >
{{content_pdf}}
</div>

<div >
{{content_excel}}
</div>

Then it looks like:

kosten fruit   totaal
3588.2         3588.1
5018.75        5018.4
3488.16        3488.16

and so 3588.2, 3588.1 has to be colored red and 5018.75, 5018.4 has to be colored red.

if I do print(content_pdf)

this is output:

<table>
<thead>
<tr><th style="text-align: right;">  kosten fruit</th></tr>
</thead>
<tbody>
<tr><td style="text-align: right;">       3588.2 </td></tr>
<tr><td style="text-align: right;">       5018.75</td></tr>
<tr><td style="text-align: right;">       3488.16</td></tr>
</tbody>
</table>

So it prints literally the html in the template

CodePudding user response:

I tried replicating the problem you're having using your own code, but I dont seem to have any problems.

Here is my code:

# index.html

       {% for value in content_pdf %}
            <span {% if value in diff_set %} style="color: red;" {% endif %}>
                {{value}}
            </span>
        {% endfor %}
# views.py

        # i dont know exactly what your 'content_pdf' contains, so this is what i did.
        content_pdf = {5018.75, 1809, 4000, 5018.4}
        diff_set = {5018.75, 3588.2, 3588.1, 5018.4}

        context = {
            'content_pdf': content_pdf,
            'diff_set': diff_set,
        }

        return render(request, "index.html", context)

Front end: difference in red

So it could be one of 2 things.

  • Your diff_set doesn't contain the exact value that content_pdf has
  • You have to pass the diff_set and content_pdf to a seperate dict and pass that into the context (which is what i did)

You could try showing {{value}} in the front-end for loop, to see if there is anything wrong/missing

Or you could try printing content_pdf (partially if its big) separate from diff_set

Hope this helps you out somehow.

CodePudding user response:

I edit the methods. And put this in the template:

<ul >
{% for value in content_pdf %}
<span {% if value in diff_set %} style="color: red;" {% endif %}>
<li>{{value}}</li>
</span>
{% endfor %}
</ul>

<ul >
{% for value in content_excel %}
<span {% if value in diff_set %} style="color: red;" {% endif %}>
<li>{{value}}</li>
</span>
{% endfor %}
</ul>

resulted in:

3588.2      3588.1
5018.75     5018.4
3488.16     3488.16
  • Related