简体   繁体   中英

Temporary modify model's field value in Django

I've got a problem with Django QuerySet:

To not turn search results into a mess I first remove all the HTML tags from text with the following code:

re.sub("<.*?>", "", note.text)

which works fine.

I need to modify all the notes and restore them back after searching is finished.

I tried this code:

def remove_tags(notes):
    for note in notes:
        note.text = re.sub("<.*?>", "", note.text)
    return notes

notes = remove_tags(Note.objects.all()) # Remove HTML tags in all the notes
# ...
found = notes.filter( # By the some reason it restores default value here
   Q(text__icontains=q) |
   Q(title__icontains=q)
)

Example text:

<span style="text-decoration:line-through">Todo</span>

When I try to access text right after calling remove_tags everything seems to be fine:

 notes = remove_tags(Note.objects.all())
 print(notes[0].text) # Will print 'Todo'

But when I do it after calling filter it looks like before:

 notes = remove_tags(Note.objects.all())
 print(notes[0].text) # Will print 'Todo'

 filtered = notes.filter(text__icontains="line-through")
 print(filtered[0].text) # Will print '<span style="text-decoration:line-through">Todo</span>'

How can I filter notes without HTML tags?

filter returns a completely new QuerySet, so everything you changed in the previous QuerySet will be forgotten.

Let me suggest a different approach:

class Note(models.Model):
    text = models.TextField()
    ...

    def text_without_tags(self):
        return re.sub("<.*?>", "", self.text)

Use this method when you need the content of the field without the tags. This is cleaner: modifying variables in place is the way to end writing spaghetti code .

Edit:

Try something like Bleach instead of regular expressions.

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