Solution 1 :

Seems to me you should do the % 3-check before you start building your protein:

def build_protein(self, request, phrase):
    if len(phrase) % 3:
        messages.error(request, 'CHAIN MUST BE DIVISIBLE BY 3')
        return ()
    protein = []
    for i in range(0, len(phrase), 3):
        amino = self.translate_amino(phrase[i: i + 3])
        if not amino:
            messages.error(request, "PROTEIN WAS NOT FOUND")
            return ()  # you might stop the loop already
        protein.append(amino)
    return protein

Solution 2 :

It’s difficult to determine from your description what it is you’re trying to achieve exactly. Looking through your code, it appears you might be calling build_protein() once, but you are seeing 3 (potentially duplicate) error messages appear in the template/view – is this correct?

If so, you would like to summarize these to only show one error message for each call to build_protein() ?

To do this, it’s probably easier to simply assign a flag to indicate whether an error condition has been hit within the loop, which consolidates multiple hits into a single boolean value, as shown here:

def build_protein(self, request, phrase):
    protein= []
    protein_error = False
    i = 0
    while i < len(phrase):
        codon = phrase[i: i + 3]
        amino = self.translate_amino(codon)
        if amino:
            protein.append(amino)
        else:
            # Setting this on time or many has the same effect
            protein_error = True
        i += 3
    if len(phrase) % 3:
        # NOTE: Better to do this test (and return) *before* the while loop
        messages.error(request, 'CHAIN MUST BE DIVISIBLE BY 3')
        return()
    else:
        if protein_error:
            # This generates only a single error message if any issues encountered
            messages.error(request, "PROTEIN WAS NOT FOUND")
        return protein

Problem :

I am currently working on a dna to protein translator. The code works pretty well. However, I’d like to improve it with the messages framework in django: https://docs.djangoproject.com/en/3.1/ref/contrib/messages/

What I did is put three if statements in the functions translate and build protein so that when this statement is true, it raises a message. However, when the message appears, they also appear the other messages.errors. Is there any way I can print the message I want.
Here’s the views.py code where I type the if statements:

class TranslatorView(View):
    def translate(self, request, phrase):
        translation = ""
        for letter in phrase:
            if letter.lower() in self.rna_mapper:
                translation += self.rna_mapper[letter.lower()].upper() if letter.isupper() else self.rna_mapper[letter]
            else: 
                translation = "INVALID DNA CHAIN"
           
        return translation

    
    def translate_amino(self, codon):
        return self.amino_mapper.get(codon, "")


   

    def build_protein(self, request, phrase):
        protein= []
        i = 0
        while i < len(phrase):
            codon = phrase[i: i + 3]
            amino = self.translate_amino(codon)
            if amino:
                protein.append(amino)
            else:
                messages.error(request, "PROTEIN WAS NOT FOUND")
            i += 3
        if len(phrase) % 3:
            messages.error(request, 'CHAIN MUST BE DIVISIBLE BY 3')
            return()
        else:
            return protein
    

And here’s the template where the messages appear:

{% extends "base.html"%}

{% block content%}

<div >
    
    <h2 class = "display-3">DNA TRANSLATED SUCCESFULLY </h2>
    <br>
    <br>
    <br>

  
    <h2>
        {{ translation }}
    </h2>


    <br>
    <br>
    <br>
   
    <h2 class = "display-4">YOUR PROTEIN IS</h2>

    <div class = "protein_image"></div>

    <br>
    <br>
    {% if messages %}
<ul class="messages">
    {% for message in messages %}
    <h2>{{ message }}</h2>
    {% endfor %}
</ul>
{% endif %}

    <h2>
        {{ protein }} 
    </h2>





    <button class= "button_with_image_save" value="Back" onclick="window.history.back()" ></button>


    
</div>   

{% endblock content%}

Having posted the code, I believe that I have to change something in the template in order to see one message instead of all of them. Perhaps indexing the messages?

Comments

Comment posted by Marcgames_YT

Yes, that was what I was trying to do

By