1

I have a model like this

class File(models.Model):

    folder=models.ForeignKey(Folder, null=True, blank=True)
    uploaded_file=models.FileField(upload_to=get_upload_path)
    pub_date = models.DateTimeField('date published',default=timezone.now())
    tag=models.ManyToManyField(FileTag)
    notes=models.TextField(max_length=200)
    uploader=models.ForeignKey(User)

    def __unicode__(self):
        return str(self.uploaded_file)
    #return os.path.basename(self.uploaded_file.name)

    def filename(self):
     return os.path.basename(self.uploaded_file.name)

i want to do somethig like this

        sr_files=File.objects.filter(filename__contains=keyword)

but i cannot use filter with filename() self defined function Plz help

Here is my template code

    {% if sr_files %}
    <ul>
    {% for rf in sr_files %}
        <li><a href="/documents/{{rf.uploaded_file}}">{{ rf.filename }}</a></li>
    {% endfor %}
    </ul>
    {% else %}
        <p>No Files Found containing {{ keyword }}</p>
    {% endif %}
wrufesh
  • 1,379
  • 3
  • 18
  • 36

2 Answers2

1

Yes, you can't use properties and function's name in filter

This can do either using list compression or generator expression as follows:

# for single File object 
sr_file = next(
          (f for f in File.objects.filter() if keyword in f.filename()), 
          None)

or

# for: all File objects contains keywords in their file path: 
sr_files = [f for f in File.objects.filter() if keyword in f.filename()]
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • yes it gives me the desired output but i want sr_files to be the collection of File type object so that i can open the file by giving the appropriate link with id in File type object Here is my template code – wrufesh May 24 '14 at 09:17
  • @wrufesh in second List-compression expression `sr_files` is indeed the collection of File type objects. Over which you can iterate in template code. – Grijesh Chauhan May 24 '14 at 09:22
  • @wrufesh Your welcome :), btw If you gets error in `rf.filename` in template code, make it property read this [Q & A](http://stackoverflow.com/questions/2468804/django-template-call-function)s – Grijesh Chauhan May 24 '14 at 09:28
1

Return the part after the last / in a path is what os.path.basename does. So you could use regex lookup

import re
File.objects.filter(uploaded_file__regex='[^/]*{}[^/]*$'.format(re.escape(keyword)))

Or simply

files = File.objects.filter(uploaded_file__contains=keyword)
# Then discard false matches
files = (f for f in files if keyword in f.filename())
okm
  • 23,575
  • 5
  • 83
  • 90