Re: Django-nonrel patches

2011-12-13 Thread Wilfred Hughes
On Dec 12, 4:46 pm, Karen Tracey  wrote:>
>
> This SELECT:
>
> >  {'sql': u'SELECT "vortaro_car"."id", "vortaro_car"."name",
> > "vortaro_car"."owner_id" FROM "vortaro_car" WHERE
> > "vortaro_car"."owner_id" IN (1)',
> >  'time': '0.001'},
> >  {'sql': u'DELETE FROM "vortaro_car" WHERE "id" IN (1)', 'time':
> > '0.000'},
>
[...]
>
> Django did explicitly find-and-delete the Car. It did not rely on the
> underlying database to do that.

Ah, absolutely right. I'll file a bug our end for this. Cheers.

Wilfred

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



Re: Django-nonrel patches

2011-12-12 Thread Wilfred Hughes
Following up on #17338 ([nonrel] supports_deleting_related_objects
database feature flag):

carljm said that:

> [Django] is (sort of) _emulating_ SQL cascading deletes, but it does so in a 
> way that doesn't assume anything at all from the backend.

I'm not sure this is correct. If I define the following models:

from django.db import models

class Person(models.Model):
name = models.CharField(max_length=100)


class Car(models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey(Person)

Related objects are indeed deleted on a sqlite Django project:

In [1]: from vortaro.models import Person, Car

In [2]: p = Person.objects.create(name='bob')

In [3]: c = Car.objects.create(name='robin reliant', owner=p)

In [4]: p.delete()

In [5]: Car.objects.all()
Out[5]: []

In [6]: from django.db import connection

In [7]: connection.queries
Out[7]:
[{'sql': u'INSERT INTO "vortaro_person" ("name") VALUES (bob)',
  'time': '0.001'},
 {'sql': u'INSERT INTO "vortaro_car" ("name", "owner_id") VALUES
(robin reliant, 1)',
  'time': '0.001'},
 {'sql': u'SELECT "vortaro_car"."id", "vortaro_car"."name",
"vortaro_car"."owner_id" FROM "vortaro_car" WHERE
"vortaro_car"."owner_id" IN (1)',
  'time': '0.001'},
 {'sql': u'DELETE FROM "vortaro_car" WHERE "id" IN (1)', 'time':
'0.000'},
 {'sql': u'DELETE FROM "vortaro_person" WHERE "id" IN (1)', 'time':
'0.000'},
 {'sql': u'SELECT "vortaro_car"."id", "vortaro_car"."name",
"vortaro_car"."owner_id" FROM "vortaro_car" LIMIT 21',
  'time': '0.000'}]

This isn't making a second query to deleting the Car model, it is
depending on the database to do this. For comparison, here's the same
on App Engine:

In [1]: from test_app.models import Person, Car

In [2]: p = Person.objects.create(name='bob')

In [3]: c = Car.objects.create(name='robin reliant', owner=p)

In [4]: p.delete()

In [5]: Car.objects.all()
Out[5]: []

In [6]: c = Car.objects.get()

In [7]: c.owner
---
DoesNotExist  Traceback (most recent call
last)
/home/wilfred/bleeding_edge/django-testapp/ in ()
> 1 c.owner

/home/wilfred/bleeding_edge/django-testapp/django/db/models/fields/
related.pyc in __get__(self, instance, instance_type)
313 rel_obj = rel_mgr.using(db).get(**params)
314 else:
--> 315 rel_obj =
QuerySet(self.field.rel.to).using(db).get(**params)
316 setattr(instance, cache_name, rel_obj)
317 return rel_obj

/home/wilfred/bleeding_edge/django-testapp/django/db/models/query.pyc
in get(self, *args, **kwargs)
349 if not num:
350 raise self.model.DoesNotExist("%s matching query
does not exist."
--> 351 % self.model._meta.object_name)
352 raise self.model.MultipleObjectsReturned("get()
returned more than one %s -- it returned %s! Lookup parameters were
%s"
353 % (self.model._meta.object_name, num, kwargs))

DoesNotExist: Person matching query does not exist.

Have I horribly misunderstood?

Wilfred

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



Re: Towards a more friendly NoReverseMatch

2011-10-19 Thread Wilfred Hughes
I've opened a ticket for improving the NoReverseMatch error:
https://code.djangoproject.com/ticket/17076

However, I'd still like to improve the documentation regarding which
patterns can be reversed. I don't fully understand the limitations
myself yet.

1. Can we provide an example of a pattern containing "|" that doesn't
work? I've successfully reversed the pattern r'^fruit/(bananas|apples)
$' above.

2. Can we give a more precise description of the limits of reversible
patterns? Is it just that the arguments / keyword arguments must match
up (looking at 
https://github.com/django/django/blob/master/django/core/urlresolvers.py#L364
this seems to be only obvious limitation)?

On Oct 12, 4:13 pm, Wilfred Hughes <wilf...@potatolondon.com> wrote:
> > >    >>> reverse('i_dont_exist')
> > >    NoReverseMatch: Reverse for 'i_dont_exist' with arguments '()' and
> > > keyword arguments '{}' not found.
>
> > > In this case, it would be nicer to have something like:
>
> > >    NoURLPattern: No patterns specified for 'i_dont_exist'.
>
> > Just on this point, I must disagree. For instance, consider if you
> > have a URL named 'i_dont_exist', and the URL pattern has two
> > positional arguments.
>
> Ah, sorry. I've been unclear. My point here is that when there /isn't/
> a URL with that name. It would be good to distinguish between having
> no regexes and not being able to reverse the regex.
>
> So, if I have an URL:
>
>     url(r'^fruit/(bananas|apples)$', some_view, name='fruit'),
>
> And I make a spelling mistake:
>
>     >>> reverse('rfuit', args=['bananas'])
>
> I would like some hint that the problem isn't in my regex. The two
> options I'm proposing are:
>
>     NoURLPattern: No patterns specified for 'rfuit'.
>
> Or:
>
>     NoReverseMatch: Reverse for 'rfuit' with arguments '()' and
> keyword arguments '{}' not found (patterns tried: []).

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



Re: Towards a more friendly NoReverseMatch

2011-10-12 Thread Wilfred Hughes
> >    >>> reverse('i_dont_exist')
> >    NoReverseMatch: Reverse for 'i_dont_exist' with arguments '()' and
> > keyword arguments '{}' not found.
>
> > In this case, it would be nicer to have something like:
>
> >    NoURLPattern: No patterns specified for 'i_dont_exist'.
>
> Just on this point, I must disagree. For instance, consider if you
> have a URL named 'i_dont_exist', and the URL pattern has two
> positional arguments.

Ah, sorry. I've been unclear. My point here is that when there /isn't/
a URL with that name. It would be good to distinguish between having
no regexes and not being able to reverse the regex.

So, if I have an URL:

url(r'^fruit/(bananas|apples)$', some_view, name='fruit'),

And I make a spelling mistake:

>>> reverse('rfuit', args=['bananas'])

I would like some hint that the problem isn't in my regex. The two
options I'm proposing are:

NoURLPattern: No patterns specified for 'rfuit'.

Or:

NoReverseMatch: Reverse for 'rfuit' with arguments '()' and
keyword arguments '{}' not found (patterns tried: []).

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



Towards a more friendly NoReverseMatch

2011-10-12 Thread Wilfred Hughes
It would be really good if we could improve the errors provided when
Django can't do reverse().

For example:

>>> reverse('i_dont_exist')
NoReverseMatch: Reverse for 'i_dont_exist' with arguments '()' and
keyword arguments '{}' not found.

In this case, it would be nicer to have something like:

NoURLPattern: No patterns specified for 'i_dont_exist'.

Alternatively, if NoReverseMatch listed the patterns it tried (similar
to template loader post-mortem given on TemplateDoesNotExist which
shows the folders tried) then a new error message would be
unnecessary:

NoReverseMatch: Reverse for 'i_dont_exist' with arguments '()' and
keyword arguments '{}' not found (patterns tried: []).

As for regex patterns that can't be reversed, it would nice to improve
the errors or improve the docs. The docs state that:

>  The main restriction at the moment is that the pattern cannot contain 
> alternative choices using the vertical bar ("|") character.

Upon reading this, I expected that Django would warn me if I tried to
reverse a pattern with a '|' in it. However, it's sometimes possible

url(r'^fruit/(bananas|apples)$', some_view, name='fruit'),

>>> reverse('fruit', args=['bananas'])
'/fruit/bananas'

There's also the issue that there are other ways of expressing
alternatives that produce NoReverseMatch, although the docs don't
really say that these are problematic:

url(r'^fruit(/location/(?P[a-z]+))?(/name/(?
P[a-z]+)/)?$', some_view,
name='fruit_with_alternative_groups'),

>>> reverse('fruit_with_alternative_groups', kwargs={'location':
'london', 'name': 'apples'})
NoReverseMatch: Reverse for 'fruit_with_alternative_groups' with
arguments '()' and keyword arguments '{'location': 'london', 'name':
'apples'}' not found.

It would be great for the error to mention that I've used '?' which
stopped reversing working. Sure, I could have multiple URL patterns
named 'fruit_with_alternative_groups', but if there's only one (or all
the patterns have this problem) then we could be more helpful.

TL;DR:

1. It'd be nice to know how many patterns were tried by reverse().
2. It'd be nice to get a warning when users try to reverse patterns
that contain alternatives with '?' or '?' (or others).
3. It'd be good to clarify the docs as to what patterns are
reversible.

Thoughts? I'll open bugs, whip up a patch or two if people are
interested.

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