Re: OR together multiple extra clauses

2012-09-14 Thread Stratos Moros
On Fri, 14 Sep 2012 17:24:21 +0300, Tomas Neme   
wrote:



I haven't done this, so I might be wrong, but...


queryset.extra(
where=['unaccent("table_name"."column_name"::text) LIKE
unaccent(%s)'],
params=['%%%s%%' % value]
)


first, wouldn't just setting params=[value] work? furthermore, isn't
that the whole point of the params thing? maybe unaccent(%%%s%%)'
params=[value].

secondly.. wouldn't chaining .extra() methods work?



Setting just params=[value] wouldn't work for me since I want to query
for rows that contain the string value, similar to how `contains` work.

Doing where=['... unaccent(%%%s%%)'], params=['value'] would produce
"... unaccent(%'value'%)" (notice the % outside the quotes) since the extra
method will quote the params before inserting them in the string.

Chaining calls to extra wouldn't work either because the where clauses will
be ANDed together.

The way I solved it is by keeping around a copy of the queryset, calling  
extra
on the copy multiple times and ORing the whole querysets. It looks  
something

like this:

original = deepcopy(queryset)
queryset & (original.extra(...) | original.extra(...))

The ORM is smart enough to realize that the two queries are identical,  
except
from the where clause and then it can combines them. The resulting SQL  
isn't

optimal but postgresql's query optimizer fixes that.

--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



OR together multiple extra clauses

2012-09-13 Thread stratos moros
Hello,

I am having some trouble using Queryset's extra method. I can't find a
way
to OR together multiple such clauses. Here's my case:

I am using Django 1.4 on PostgreSQL 9.2 and I need to perform accent
insensitive queries on some models. In Postgres, this is handled by
the
unaccent function.

The best way I've found to perform this query through Django's ORM is
by using
the extra method, like so:

queryset.extra(
where=['unaccent("table_name"."column_name"::text) LIKE
unaccent(%s)'],
params=['%%%s%%' % value]
)

Since I need to perform similar queries all over my codebase, I've
written
some wrappers around Django's lookups, so the above can be substituted
by:

queryset = contains_ai(queryset, attribute_name, value)

The problem I'm having is that depending on the request I need to
compose
multiple such queries, sometimes with OR statements. As far as I know
the only
way to OR together multiple filters is by using Q objects, but there
is no way
to use extra (or even raw sql) with them. I could write both OR
clauses on the
where clause, but then I will no longer be able to conditionaly
compose
multiple such statements together.

Is there a way to OR together results form the extra method?

Thanks for your help!

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Re: Use primary key in filenames on FileFields

2011-09-06 Thread Stratos Moros
This wouldn't work. It will work for updates, but when a new Decision
object is created, "get_file_path" runs before the object is saved and
self.id will be None.

On Sep 5, 6:51 pm, Bingimar <bjarni.julius...@gmail.com> wrote:
> try this
>
> def get_file_path(instance, filename):
>     path = 'your upload directory'
>     extension = filename.split('.')[-1].lower()
>     new_file_name = self.id
>
>     return '%(path)s/%(filename)s.%(extension)s' %
>                                                    {
>                                                        'path': path,
>                                                        'filename':
> new_file_name',
>                                                        'extension':
> extension
>                                                    }
>
> class Decision(m.Model):
>     ...
>     decision = m.FileField(upload_to=get_file_path)
>
> On Sep 5, 11:01 am, Stratos Moros <s.mo...@indev.gr> wrote:
>
>
>
> > I forgot to mention that i have imported models like this:
>
> > import django.db.models as m
>
> > This should explain the first two lines.
>
> > On Mon, Sep 5, 2011 at 12:28 PM, Stratos Moros <s.mo...@indev.gr> wrote:
> > > Hello,
>
> > > I have a model that includes a FileField. When the user uploads a file
> > > via the admin interface, I want the file to be saved as 'upload_to/
> > > primary_key/original_filename'. Since the object will not be saved in
> > > the database when the user uploads the file, it will not have a
> > > primary key at that point. This is my workaround:
>
> > > class Decision(m.Model):
> > >    ...
> > >    decision = m.FileField(upload_to='base_dir/')
> > >    ...
>
> > >    def save(self, *args, **kwargs):
> > >        """ custom save to use pk on filename """
> > >        #save once to get a pk
> > >        super(Decision, self).save(*args, **kwargs)
>
> > >        #get info about the file
> > >        uploaded = self.decision
> > >        old_path = self.decision.name
> > >        basedir, filename = os.path.split(old_path)
> > >        new_path = os.path.join(basedir, str(self.pk), filename)
>
> > >        #create the new file, delete the one django created
> > >        uploaded.storage.save(new_path, uploaded)
> > >        uploaded.storage.delete(old_path)
>
> > >        #assign new path and save again
> > >        self.decision = new_path
> > >        super(Decision, self).save(*args, **kwargs)
>
> > > This works, but seems to be a bit on the hacky side. Basically, I'm
> > > letting FileField upload the file to the 'upload_to' path and then
> > > move it to its correct path when the object has a primary key.
>
> > > I was wondering if there is a better way to do this. Are there any
> > > cases where my code wouldn't work?
>
> > > Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Use primary key in filenames on FileFields

2011-09-05 Thread Stratos Moros
Hello,

I have a model that includes a FileField. When the user uploads a file
via the admin interface, I want the file to be saved as 'upload_to/
primary_key/original_filename'. Since the object will not be saved in
the database when the user uploads the file, it will not have a
primary key at that point. This is my workaround:


class Decision(m.Model):
...
decision = m.FileField(upload_to='base_dir/')
...

def save(self, *args, **kwargs):
""" custom save to use pk on filename """
#save once to get a pk
super(Decision, self).save(*args, **kwargs)

#get info about the file
uploaded = self.decision
old_path = self.decision.name
basedir, filename = os.path.split(old_path)
new_path = os.path.join(basedir, str(self.pk), filename)

#create the new file, delete the one django created
uploaded.storage.save(new_path, uploaded)
uploaded.storage.delete(old_path)

#assign new path and save again
self.decision = new_path
super(Decision, self).save(*args, **kwargs)


This works, but seems to be a bit on the hacky side. Basically, I'm
letting FileField upload the file to the 'upload_to' path and then
move it to its correct path when the object has a primary key.

I was wondering if there is a better way to do this. Are there any
cases where my code wouldn't work?

Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Re: Use primary key in filenames on FileFields

2011-09-05 Thread Stratos Moros
I forgot to mention that i have imported models like this:

import django.db.models as m

This should explain the first two lines.

On Mon, Sep 5, 2011 at 12:28 PM, Stratos Moros <s.mo...@indev.gr> wrote:
> Hello,
>
> I have a model that includes a FileField. When the user uploads a file
> via the admin interface, I want the file to be saved as 'upload_to/
> primary_key/original_filename'. Since the object will not be saved in
> the database when the user uploads the file, it will not have a
> primary key at that point. This is my workaround:
>
>
> class Decision(m.Model):
>    ...
>    decision = m.FileField(upload_to='base_dir/')
>    ...
>
>    def save(self, *args, **kwargs):
>        """ custom save to use pk on filename """
>        #save once to get a pk
>        super(Decision, self).save(*args, **kwargs)
>
>        #get info about the file
>        uploaded = self.decision
>        old_path = self.decision.name
>        basedir, filename = os.path.split(old_path)
>        new_path = os.path.join(basedir, str(self.pk), filename)
>
>        #create the new file, delete the one django created
>        uploaded.storage.save(new_path, uploaded)
>        uploaded.storage.delete(old_path)
>
>        #assign new path and save again
>        self.decision = new_path
>        super(Decision, self).save(*args, **kwargs)
>
>
> This works, but seems to be a bit on the hacky side. Basically, I'm
> letting FileField upload the file to the 'upload_to' path and then
> move it to its correct path when the object has a primary key.
>
> I was wondering if there is a better way to do this. Are there any
> cases where my code wouldn't work?
>
> Thanks.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.