Re: Not calling things twice in templates
On Mon, Jun 3, 2013 at 1:20 PM, Shai Berger wrote: > On Monday 03 June 2013, Russell Keith-Magee wrote: > > Alternatively, add new sub tags to {% for %}: > > > > {% for bee in my_bonnet.bees %} > > {% pre %} > > > > {% body %} > > {{ bee }} > > {% post %} > > > > {% empty %} > > No bees in your bonnet. > > {% endfor %} > > > > but that's starting to get verbose, and leaves ambiguous what to do with > > content appearing between the opening {% for %} and the {% pre %} > > > It's also sort of available already: > > I'm fully aware that it's *possible* to handle already. The point is that it's such a common use case that is should be easy to render without requiring an extra 4 lines of obscure template logic, an extra 2 levels of indentation, or an expensive double calculation. Yours, Russ Magee %-) -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not calling things twice in templates
On Mon, Jun 3, 2013, Russell Keith-Magee wrote: >> But this is another common pattern: >> >> {% if my_bonnet.bees %} >> >> {% for bee in my_bonnet.bees %} >> {{ bee }} >> ... >> >> The problem here is that my_bonnet.bees gets asked for twice, and it could >> be my.bonnet(), some very expensive function. >Any other syntax I can think of requires introducing another indentation >level. Have you got a specific suggestion for how to address this? Not really. I wasn't even sure if would be considered much of an issue. But I can think of two: * introducing a template syntax that means "don't re-fetch" perhaps: !my_bonnet.bees or: my_bonnet.bees.cached I don't know if the latter would even be possible. * managing it at the function level The template author might not even know which functions are expensive. So perhaps it should be the function writer's responsibility to make take care of this: @expensive def bees(self): which will tell the template system not to re-evaluate it while serving the same request. I think I like this second suggestion better, because it keeps templates as simple as possible. And this way, the template author won't have to worry about keeping up-to-date with re-written functions that have become more expensive or less expensive. Daniele -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Why apps have to have unique names? [related with subapps and name collision]
Hi. The motivation to this question is that if I want to implement "copies" of an app within an website (for instance, a stackoverflow-like where each app is a Q&A for its own, but with modifications on templates, urls, etc.), as far as I'm understanding: (1) each "copy" has to change its name, names of all calls of templates, views, etc due to name collision and (2) each copy must be an app on its own without any dependencies on other apps with models/templates/urls, because otherwise the dependent apps would also have to be "copied", names changed, etc. In a previous post I suggested generalizing templates and url search to be used within subapps (apps with folder inside another app), which I found was a way of allowing what I wanted to do. There was a criticism that during the discussion that I (mostly) ignored, but while re-reading it, I understood its meaning and its importance to a discussion by itself. The criticism was from Shai Berger, that correctly pointed out that Django uses unique app names [1], and what I didn't understood at the time was that this forbids any possibility of using subapps the way I was suggesting or in any way that might help. Motivated by that criticism, I want to ask: why apps have to have unique names? To try to answer this question on the code, I did a simple search on Django code. This is far from rigorous, but gives some nice results. The search was simple: regex of r"settings.INSTALLED_APP" and regex of r".split('.')[-2]". Afterwards, I read the code to understand which dependencies it has on the labeling. Here are the results: ## Usage of settings.INSTALLED_APP (regex: settings.INSTALLED_APP) # To check admin existence, uses full path (import_module) /django/contrib/admin/__init__.py:24: for app in settings.INSTALLED_APPS: # To check specific app existence, uses full path (import_module) /django/contrib/admin/templatetags/admin_static.py:6: if 'django.contrib.staticfiles' in settings.INSTALLED_APPS: /django/contrib/comments/__init__.py:16: if comments_app not in settings.INSTALLED_APPS: /django/contrib/gis/tests/__init__.py:113: settings.INSTALLED_APPS = list(self.old_installed) + new_installed /django/contrib/gis/tests/__init__.py:125: settings.INSTALLED_APPS = self.old_installed /django/contrib/messages/tests/base.py:16: 'django.contrib.auth' not in settings.INSTALLED_APPS, /django/contrib/messages/tests/base.py:214: lambda app:app!='django.contrib.messages', settings.INSTALLED_APPS), /django/contrib/messages/tests/base.py:239: lambda app:app!='django.contrib.messages', settings.INSTALLED_APPS), /django/contrib/sitemaps/tests/flatpages.py:8: @skipUnless("django.contrib.flatpages" in settings.INSTALLED_APPS, /django/contrib/sitemaps/tests/http.py:88: @skipUnless("django.contrib.sites" in settings.INSTALLED_APPS, # for finding static; use full path of the app /django/contrib/staticfiles/finders.py:122: apps = settings.INSTALLED_APPS # for binding commands to the management. Requires unique app to avoid commands collision. /django/core/management/__init__.py:101: apps = settings.INSTALLED_APPS # for binding commands to the management. Requires unique app to avoid commands collision. /django/core/management/__init__.py:319: options += [(a.split('.')[-1], 0) for a in settings.INSTALLED_APPS] # for importing the 'management' module within each installed app, to register dispatcher events. /django/core/management/commands/flush.py:35: for app_name in settings.INSTALLED_APPS: # for importing the 'management' module within each installed app, to register dispatcher events (lacks DRY principle: command used is the same as previous file.) /django/core/management/commands/syncdb.py:38: for app_name in settings.INSTALLED_APPS: # for the 'models' of the db. It uses django.utils.importlib.import_module on the full app's path. Class uses _label_for for defining a "name" for the app, which requires unique app /django/db/models/loading.py:61: for app_name in settings.INSTALLED_APPS: /django/db/models/loading.py:143: for app_name in settings.INSTALLED_APPS: # To check whether the model is installed. It uses full paths of the package /django/db/models/options.py:71: self.installed = re.sub('\.models$', '', cls.__module__) in settings.INSTALLED_APPS # To find templatetags. It stores the full path of the module /django/template/base.py:1271: for app_module in ['django'] + list(settings.INSTALLED_APPS): # To find templates. It stores the full path of the module /django/template/loaders/app_directories.py:19: for app in settings.INSTALLED_APPS: # To find templates. Depends on the pkg_resources.resource_string to tell wether it returns app name of full app name /django/template/loaders/eggs.py:23: for app in settings.INSTALLED_APPS: # To check specific app existe
Re: Composite fields once again
On 2 kesä, 23:20, Luke Sneeringer wrote: > On Jun 2, 2013, at 8:22 AM, Michal Petrucha wrote: > > > GenericForeignKey and nontrivial field types > > > > > As I've indicated in my proposal, just casting any value to a string > > and then performing a reversible transformation on such strings may > > work well enough for string and integer database columns, not so much > > for things like dates, timestamps IP addresses or other similar types. > > > Any ideas on how to make this work? Should I try to extend the backend > > API to include explicit casts for each nontrivial column type to a > > string representation equal to the one used by Python? Or should I > > just document this as unsupported? > > There's already a `db_type` method that you can override (that receives a > `connection` object) for the actual database type. It's pretty easy to do > something to the effect of (for instance): > > if 'postgres' in connection['ENGINE']: > return 'uuid' > if 'mysql' in connection['ENGINE']: > return 'char(36)' > [...] > > However, having done some work myself on trying to create non-trivial field > subclasses, it's everything after that which gets difficult. Django provides > an overridable method to cast the value, but nothing for anything else in the > expression (the field or the operator), which are hard-coded into the > backend. (This is a source of frustration for me personally, because it makes > it very difficult to write classes for, say, PostgreSQL arrays, without > either resorting to massively ugly syntax or subclassing nearly every single > class involved in the process of creating a query (Manager, QuerySet, Query, > WhereNode...) > > I ultimately went through the subclass-half-the-world technique quite > recently (a couple of weeks ago), as I want some non-trivial custom fields > for a new project I am about to start for my company (sadly, the project is > private, although I'd be happy to share field code if it would help in any > way). What I ended up doing is checking the Field subclass for a custom > `get_db_lookup_expression` method (that's not a Django field method -- I made > it up), and then my Field subclasses could use that to return a full > expression in the form "{field} = {value}". If the method is present and I > get something (other than None) back from that method, then use it, otherwise > I pass it on to the DatabaseOperators class for its usual processing. Using > that method prevents me from having to modify a monolithic DatabaseOperators > subclass for each new field I add (it seems to me that fields should know how > to perform their lookups). > > The other challenge was defining the QuerySet lookup expressions. Django > essentially hard-codes the things it understands for lookups (e.g. > Foo.objects.filter(bar__gt=5) being transformed into "select ... from app_foo > where bar > 5"). The set of lookup suffices (exact, gt, gte, lt, lte, etc.) > is, sadly, also essentially hard-coded. I wrote an ArrayField to use > PostgreSQL arrays, and really wanted a way to be able to lookup based on the > length of the array (so, something like `Foo.objects.exclude(photos__len=0)`, > for instance, to give me all Foos with no photos). I did manage to make that > work, but it was a struggle. Also, the set of lookup suffices is universal, > even though some of them don't make sense on some fields ("year" on > IntegerField, for instance). > > So, my ideas on getting non-trivial field subclasses to work is basically: > > 1. Make fields be the arbiter of what lookup types they understand. > (IntegerFields shouldn't understand "year"; maybe someone's ArrayField > subclass does understand "len".) This probably needs to be something that can > be determined on the fly, as composite fields will probably need lookup types > corresponding to their individual sub-fields. > > 2. Make lookup types chainable. In the Array "len" example, > `photos__len__gt=5` makes sense. > > 3. Make it so fields define how they are looked up based on database engine > and lookup type. > > Moving these things into the Field implementation (rather than in the > backend) should mean that non-trivial field subclasses become much easier. > It'll also eliminate the need for, say, django.contrib.gis to have an > entirely different set of backends -- a large reason gis jumps through those > hoops (as best as I can tell from reading it; disclaimer: I am not a > contributor) is to work around the restrictions being described. > > I hope that helps your thinking. I have this stuff fresh in my head because > I've just worked on an implementation for PostgreSQL arrays and composite > fields that I need for my work. While I've thought a decent bit about > extensibility (for my own purposes), I haven't open-sourced it largely > because I know I haven't solved all the problems yet. Having read your > e-mail, I now ho
Re: Why apps have to have unique names? [related with subapps and name collision]
2013/6/3 Jorge C. Leitão Motivated by that criticism, I want to ask: why apps have to have unique > names? > Hi Jorge, Django assumes that a model can be identified by (app_name, model_name). Long ago — 8 years ago — it didn't seem to be a problem. I'm not sure your research covers all the consequences of this assumption. Anything that hits the app cache depends on this assumption: - the target of foreign keys can be expressed as 'app_name.ModelName' - the fixture format identifies models with app_name.ModelName - several settings have a value in the form app_name.ModelName - django.contrib.contenttypes uses (app_name, model_name) to identify each model - since permissions are tied to content types, this assumption bleeds to django.contrib.auth - etc. Lifting the requirement of uniqueness would require switching anything that uses the app_name.ModelName format to full.path.to.app.ModelName. That would be quite disruptive, not only for Django, but for the entire ecosystem of apps, starting with contrib apps. The real question is -- what's the story for authors of pluggable apps ? for users of the framework ? As far as I know, the explanation for this behavior lies in history more than in a design decision. Until now, no one judged this to be enough of a problem to make a proposal to fix it. To be honest, it's frighteningly hard to fix. Even app-loading (ticket #3591) doesn't tackle it. -- Aymeric. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Why apps have to have unique names? [related with subapps and name collision]
Is this not almost trivial to work around by creating a new module 'newapp', importing the original app code from it, and then using 'path.to.newapp' as a new "copy" of the app in INSTALLED_APPS? Yishai On Mon, 03 Jun 2013 12:24:38 +0300, Aymeric Augustin wrote: 2013/6/3 Jorge C. Leitão Motivated by that criticism, I want to ask: why apps have to have unique names? Hi Jorge, Django assumes that a model can be identified by (app_name, model_name). Long ago — 8 years ago — it didn't seem to be a problem. I'm not sure your research covers all the consequences of this assumption. Anything that hits the app cache depends on this assumption: - the target of foreign keys can be expressed as 'app_name.ModelName' - the fixture format identifies models with app_name.ModelName - several settings have a value in the form app_name.ModelName - django.contrib.contenttypes uses (app_name, model_name) to identify each model - since permissions are tied to content types, this assumption bleeds to django.contrib.auth - etc. Lifting the requirement of uniqueness would require switching anything that uses the app_name.ModelName format to full.path.to.app.ModelName. That would be quite disruptive, not only for Django, but for the entire ecosystem of apps, starting with contrib apps. The real question is -- what's the story for authors of pluggable apps ? for users of the framework ? As far as I know, the explanation for this behavior lies in history more than in a design decision. Until now, no one judged this to be enough of a problem to make a proposal to fix it. To be honest, it's frighteningly hard to fix. Even app-loading (ticket #3591) doesn't tackle it. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not calling things twice in templates
2013/6/3 Andre Terra : > Well, Russ, you asked for suggestions, so here's a couple half-hearted > attempts. > > Perhaps we could allow for if clauses in the with block or vice-versa? It > could be argued that it would reduce readability and/or induce confusion > with conditional expressions[0], and I would have to agree. > > {% with my_bonnet.bees as bees if my_bonnet.bees %} > {# could be confused with conditional expressions #} > > {% for bee in bees %} > {{ bee }} > {% endfor %} > > {% else %} > No bees! > {% endwith %} What about: {% with nonempty my_bonnet.bees as bees %} {% for bee in bees %} {{ bee }} {% endfor %} {% endwith %} -- Patryk Zawadzki I solve problems. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Making __repr__ safe by default
2013/5/19 Karen Tracey : > I agree with Anssi, repr should stay as-is. I do a lot of shell/pdb work and In interactive mode it's just as easy to call __unicode__ as it is to call __repr__. On the other hand __repr__ is used by automated tools such as crash reporters (raven). > I can't recall ever encountering a problem with "unsafe" repr. We had it explode a number of times when coupled with postgres. In that case instead of the original exception, all you get is: psycopg2.ProgrammingError: current transaction is aborted, commands ignored until end of transaction block > I think many > people would find it annoying if suddenly repr would tell you no more than > the pk of the object. I'd argue that the PK is actually more important than whatever __unicode__ returns. It's really annoying to find a stack trace that only contains product's title when you have tens of millions of products on production and title is not an indexed field. And by that time it's already too late to override __repr__. On the other hand it's fairly easy to extend __repr__ to display other information if you find it more useful than the PK. Backward compatibility should not be a concern here as no code should depend on whatever __repr__ chooses to return. -- Patryk Zawadzki I solve problems. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Why apps have to have unique names? [related with subapps and name collision]
On Mon, Jun 03, 2013 at 01:04:34PM +0300, Yishai Beeri wrote: > Is this not almost trivial to work around by creating a new module > 'newapp', importing the original app code from it, and then using > 'path.to.newapp' as a new "copy" of the app in INSTALLED_APPS? Not really. At least not for models. There is some magic, I'm not sure if it's in AppCache or in the model metaclass, which inspects the import path in which the model class is located and uses it to identify the model class. That means, if you just import another application's models, they will still be recoginzed as belonging to the original application. Michal signature.asc Description: Digital signature
Re: Not calling things twice in templates
Hi all. In the past, I once proposed a decorate template tag, but it was disapproved back then. This would be another solution, to make the template language a lot more powerful. 1. First you define a decorator, for the behaviour you'd like to have. The "data" parameter indicates the receiving parameters. {% define my_special_for "data" %} {% if data %} {% for i in data %} {% placeholder %} {% endfor %} {% else %} nothing found... {% endif %} {% enddefine %} This definition can be used as follows: {% decorate my_special_for data %} {{ i.value }} {% enddecorate %} Not sure about the namings, but personally, I'm very convinced about this appoach. There shouldn't be too much logic in the template tags itself. Another nice thing is that the and tags happen to be in exact the same scope which increases readability and the posibilities for automatic validation. An extended version would create a second {% placeholder %} block for the "nothing found..." part. If this is an acceptable appoach, I'm willing to contribute this to Django core, and write unit-tests and such. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not calling things twice in templates
By the way, this could also be implemented using just files. The way {% include %} works for macros. If that's preferred. That becomes: {% decorate "my_special_for.html" data %} {{ i.value }} {% enddecorate %} Le lundi 3 juin 2013 13:38:29 UTC+2, Jonathan Slenders a écrit : > > Hi all. In the past, I once proposed a decorate template tag, but it was > disapproved back then. > This would be another solution, to make the template language a lot more > powerful. > > 1. First you define a decorator, for the behaviour you'd like to have. The > "data" parameter indicates the receiving parameters. > > {% define my_special_for "data" %} > {% if data %} > > {% for i in data %} > {% placeholder %} > {% endfor %} > > {% else %} > nothing found... > {% endif %} > {% enddefine %} > > > This definition can be used as follows: > > {% decorate my_special_for data %} > {{ i.value }} > {% enddecorate %} > > > Not sure about the namings, but personally, I'm very convinced about this > appoach. There shouldn't be too much logic in the template tags itself. > > Another nice thing is that the and tags happen to be in exact > the same scope which increases readability and the posibilities for > automatic validation. > > An extended version would create a second {% placeholder %} block for the > "nothing found..." part. > > If this is an acceptable appoach, I'm willing to contribute this to Django > core, and write unit-tests and such. > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Make sure QuerySet.get() does not fetch more rows than it absolutely needs
Here's the ticket: https://code.djangoproject.com/ticket/6785 tl;dr: Calling .get() on a badly filtered queryset can result in lots of database rows being fetched and wrapped in Python objects for no gain. Currently .get() logic is as follows: clone the queryset, prepopulate its full cache, check if more than one row was returned and if so, raise MultipleObjectsReturned. This works fine if the query returns two or five rows. It's not so fine if the query results in thousands or millions of rows being returned. While working on a large online store we had one of the production servers die while trying to fetch twenty something million rows because of a programming error that resulted in wrong Q object being used as a filter. The only reason all rows are fetched is to return an accurate counter as part of the exception message. This counter is not accessible programmatically and having the exact number there is of little value. The ticket proposes to add a safeguard by limiting the database to at most two results. The logic then is simple: if zero rows are returned, raise ObjectDoesNotExist, if two, raise MultipleObjectsReturned. The latter could possibly execute a second COUNT query if DEBUG is enabled and the counter is deemed important enough to keep. Of course you can work around the whole problem by not writing buggy code but we all know how it works. In the mentioned case even unit tests did not help as there were not enough records in the database to trigger MultipleObjectsReturned. Related pull request: https://github.com/django/django/pull/1139 -- Patryk Zawadzki I solve problems. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Why apps have to have unique names? [related with subapps and name collision]
Related thread: https://groups.google.com/d/topic/django-developers/9piN0wRFbLs/discussion -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: RFC: "universal" view decorators
Attempting to make decorators anticipate every usage is the wrong approach. In Django, the sole interface to a view is as a callable that accepts an `HttpRequest` and turns it into an `HttpResponse` or exception. Django the framework doesn't actually need to support class-based views--because CBVs are just another way to build view callables. View callables are an elegant abstraction that keeps the core of Django, and the decorators it provides, simple. Trying to anticipate all the ways of building view callables is not only complex, it is impossible. Why shouldn't I be able to use the built-in decorators with my own implementations of class-based views? If the built-in decorators' implementations are simple, I will be able to provide an adapter to use them with my CBV system. There are many useful decorators built-in to Django and in the wild, and my adapter will work with all of them, because they treat views as simple callables. `method_decorator` is the right idea, but it is painful to use. It requires a tedious empty `dispatch` method, just to have something to decorate. Using decorators to modify views makes sense, because decoration is the only way to modify the functionality of a callable. Classes, however, have much more powerful ways of adding optional functionality: multiple inheritance. # `DecoratorMixin` `DecoratorMixin` is a class factory that converts any view decorator into a class-based view mixin. It works as you would expect with inheritance--MRO provides the same ordering that function decorators do, and multiple inheritance allows the mixins to be composed naturally. Inheriting from a decorated view decorates the subclass as you would expect. It averts the need for the annoying empty `dispatch` method in each class that wants to use a decorator. Its implementation is simple: https://gist.github.com/gavinwahl/5694349. This is a complete implementation, and is all that's necessary to use view decorators with Django's CBVs. I use this code in all my projects with great success. [Here is an example](https://github.com/fusionbox/django-authtools/blob/master/authtools/views.py#L94) of its use in a reimplementation of Django's auth views as CBVs. Using it is easy and intuitive: LoginRequiredMixin = DecoratorMixin(login_required) class LoginRequiredAndCsrfMixin(DecoratorMixin(login_required), DecoratorMixin(csrf_protect)): """ Inheriting from this class is the same as decorating your view thus:: @login_required @csrf_protect def someview(request): pass """ pass class SomeView(LoginRequiredMixin, View): # ... I propose `DecoratorMixin` be added to Django. It retains compatibility with all existing decorators, elegantly adapts functional decorators to good object-oriented practices, and has a simple implementation. 'Universal' decorators don't accommodate existing third-party code, contain complex magic, and annul one of the most elegant principles of Django: views are simply callables. On Thursday, September 15, 2011 2:44:39 PM UTC-6, Jacob Kaplan-Moss wrote: > > Hi folks -- > > I'd like to convert all the view decorators built into Django to be > "universal" -- so they'll work to decorate *any* view, whether a > function, method, or class. I believe I've figured out a technique for > this, but I'd like some feedback on the approach before I dive in too > deep. > > Right now view decorators (e.g. @login_required) only work on > functions. If you want to use a decorator on a method then you need to > "convert" the decorator using method_decorator(original_decorator). > You can't use view decorators on class-based views at all. This means > making a class-based view require login requires this awesomeness:: > > class MyView(View): > @method_decorator(login_required) > def dispatch(self, *args, **kwargs): > return super(MyView, self.dispatch(*args, **kwargs) > > This makes me sad. It's really counter-intuitive and relies on a > recognizing that functions and methods are different to even know to > look for method_decorator. > > #14512 proposes a adding another view-decorator-factory for decorating > class-based views, which would turn the above into:: > > @class_view_decorator(login_required) > class MyView(View): > ... > > This makes me less sad, but still sad. Factory functions. Ugh. > > I want @login_required to work for anything:: > > @login_required > class MyView(View): > ... > > class Something(object): > @login_required > def my_view(self, request): > ... > > @login_required > def my_view(request): > ... > > > Now, back in the day we somewhat had this: decorators tried to work > with both functions and methods. The technique turned out not to work > (
Username Independence in Auth Forms
Some of the built-in auth forms only work on user models whose `USERNAME_FIELD` is `username`. It is possible to remove this constraint and allow them work on any user model. [django-authtools][1] demonstrates this possibility. The two forms in question are `UserCreationForm` and `UserChangeForm`. Both of them explicitly add a `username` field instead of letting the ModelForm add it automatically. For `UserChangeForm`, simply removing the `username` field from the form achieves user-model independence. `UserCreationForm` is slightly more complicated, due to the `clean_username` method. `clean_*` methods have to be named after their field, so it's hard to add one when you don't know the name of the field. This can be overcome by adding a validator to the field while initializing the form [2]. The reason the forms do have a `username` field currently is to change the help text, validation error messages, and validators. I don't think this should happen in the form, because all of these can be set on the model field instead. This could cause a backwards-compatibility concern if someone wasn't validating usernames in their custom User model (they are already validated in `auth.User`), and relied on the form instead. I don't think this is a serious issue--it only occurs if someone is using a custom User model, using the built-in forms, and not doing any username validation in their model. If this approach sounds reasonable, I will submit it in the form of a patch. [1]: https://github.com/fusionbox/django-authtools/blob/master/authtools/forms.py [2]: https://github.com/fusionbox/django-authtools/blob/master/authtools/forms.py#L61 -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Username Independence in Auth Forms
On 3 juin 2013, at 20:01, gavinw...@gmail.com wrote: > Some of the built-in auth forms only work on user models whose > `USERNAME_FIELD` is `username`. Hi Gavin, The current code assumes that if you write a custom model, you'll also write the corresponding custom forms. You may want to have a look at https://code.djangoproject.com/ticket/19353 which describes the same problem (as far as I can tell). -- Aymeric. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Username Independence in Auth Forms
> The current code assumes that if you write a custom model, you'll also write the corresponding custom forms. Right. This is what I am proposing be fixed. On Mon, Jun 3, 2013 at 12:31 PM, Aymeric Augustin < aymeric.augus...@polytechnique.org> wrote: > On 3 juin 2013, at 20:01, gavinw...@gmail.com wrote: > > > Some of the built-in auth forms only work on user models whose > `USERNAME_FIELD` is `username`. > > Hi Gavin, > > The current code assumes that if you write a custom model, you'll also > write the corresponding custom forms. > > You may want to have a look at > https://code.djangoproject.com/ticket/19353which describes the same problem > (as far as I can tell). > > -- > Aymeric. > > > > > -- > You received this message because you are subscribed to a topic in the > Google Groups "Django developers" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/django-developers/XxaZ50SxPj4/unsubscribe?hl=en > . > To unsubscribe from this group and all its topics, send an email to > django-developers+unsubscr...@googlegroups.com. > To post to this group, send email to django-developers@googlegroups.com. > Visit this group at http://groups.google.com/group/django-developers?hl=en > . > For more options, visit https://groups.google.com/groups/opt_out. > > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Make sure QuerySet.get() does not fetch more rows than it absolutely needs
On Monday 03 June 2013, Patryk Zawadzki wrote: > Here's the ticket: > > https://code.djangoproject.com/ticket/6785 > > tl;dr: Calling .get() on a badly filtered queryset can result in lots > of database rows being fetched and wrapped in Python objects for no > gain. > tl;dr: There's a general, valuable optimization to be made here, but it should be implemented at a lower level. I have raised a related issue about a year and a half ago[0], thinking (mistakenly) that it was mostly an Oracle issue. Ian Kelly had pointed me in the right direction, but then life happened... The problem is that for all single-row queries except aggregates, Django uses the same strategy as used in get (and which you kept using in your patch): limit the query (usually) properly, then fetch until no more records are retrieved (fetching in done in chunks using fetchmany(), and not using fetchall()). For single-row queries, this means two fetches; an unnecessary network roundtrip, for each such query, unless the backend or underlying driver take care to prevent it. On Oracle, at least, nobody does. What we should do instead, in my opinion, is stop fetching as soon as a chunk arrives that isn't full. This alone should reduce the number of network accesses significantly on most Django projects. While we're doing that, we could also define a new mode of sql execution (see SQLCompiler.results_iter(), in django.db.models.sql.compiler): Next to the current SINGLE (which uses fetchone()) and MULTI (the chunked loop described above) we could have SINGLE_VERIFY, which always fetches a single chunk of size 2. Make get() use that, and #6785 is fixed, while improving performance -- rather than hurting it on correct usage, like the proposed patch[1] does. Assuming nobody raises objections, I intend to propose a patch along these lines sometime in the coming weeks (it's one of a few things on my to-do list), but I wouldn't mind at all if someone beat me to it. Hope this helps, Shai. [0] https://groups.google.com/d/msg/django-developers/SQ0Pltt_f0M/3ccQn0aauiEJ [1] https://github.com/django/django/pull/1139 -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not calling things twice in templates
Hi, On Monday 03 June 2013, Andre Terra wrote: > Well, Russ, you asked for suggestions, so here's a couple half-hearted > attempts. > ... and here's a couple of other ones, mostly inspired by those: > {% with my_bonnet.bees as bees if my_bonnet.bees %} > {% if my_bonnet.bees with my_bonnet.bees as bees %} The only problem I see with these is the repetition -- we could just allow "as" on {% if %}: {% if my_bonnet.bees as bees %} {% for bee in bees %} {{ bee }} {% endfor %} {% else %} No bees! {% endif %} Another (halfbaked) idea: Allow separating the "in" from the {% for %}. Let a {% for %} with no "in" make a collection "current", and then its elements can be iterated over by, say, {% each %}: {% for my_bonnet.bees %} {% each bee %} {{ bee }} {% endeach %} {% empty %} No bees! {% endfor %} The problem I see with this: it's perhaps a tad too implicit. HTH, Shai. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
[GSoC] Revamping validation framework and merging django-secure once again
Hello! I'm really happy that I've been accepted as a Google Summer of Code student. I will work at revamping validation framework and merging django-secure this summer. I created this thread to start discussion (especially about public API) and get some feedback as well as to share progress. Any comments are welcomed! You can find my proposal as a gist here [1], but I'm going to describe my ideas in short here. [1] https://gist.github.com/chrismedrela/82cbda8d2a78a280a129 My proposal consists of two parts: the first one is revamping validation framework. Don't be confused with form validation - I mean validation of (mainly) apps and models triggered before launching server (or directly by `python manage.py validate` command). The main drawback of the existing framework is that it's monolithic and therefore hard to customize. The second part of my project is merging django-secure using the new refactored framework. That will be a proof that the framework is customizable. Let's start with validation. The validation is done every time you run your Django application. It prevents from misconfigurations (for example missing `upload_to` attribute of FieldFile) or invalid models (a model with a `id` field without `primary_key` set to True). Some apps need custom validation, for example admin app need to check all registered ModelAdmin instances. The new validation framework will cover some other use cases. For example, your apps will be able to check dependencies. Let's start with validating a field. Consider existing FieldFile field. It requires an `upload_to` attribute. How could you check if it's set using the new framework? class FieldFile(Field): (... lots of stuff ...) def validate_upload_to(self): if not self.upload_to: yield Error(obj=self, msg="required 'upload_to' attribute", explanation="Django need to know the directory where uploaded files should be stored.", hint="Add \"upload_to = 'path/to/directory/on/server'\" to model %(model)s in file %(model_file)s.") All methods starting with `validate_` will be called automagically at validation stage. You don't have to trigger it manually. The methods shouldn't have any parameters (excluding `self`). They should return list of errors and warnings or they should yield each of them (like in the example). You can see a new `Error` structure with the following fields: `obj`, `msg`, `explanation` and `hint`. The last two attributes are separated from `msg` in order to force Django developers to give its users really useful, user-friendly error messages with a list of solutions and explanation of a problem. I think that Django should be an intelligent framework that make a conversation with its users. The new framework will introduce a concept of warnings which are really similar to errors expect that they allow you to run server. A warning have the same fields: `obj`, `msg`, `explanation` and `hint`. Warnings will be used while merging django-secure. Not only fields can be validated, but also: models, managers and apps. In case of models, a developer has to write a *class method*, because we validate a model which is a class, not an instance. In case of apps, you can create `validation.py` file which should contain functions. After refactoring validation framework, I will focus on merging django-secure. django-secure is a set of tests improving security of django applications. I won't implement new features, that would be only fitting it to the new framework. I will publish proposal of its new public API in the future. Feel free to comment and criticize! -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: [GSoC] Revamping validation framework and merging django-secure once again
Hi Christopher, Overall, this looks like a great project and I look forward to the more flexible validation hooks. As the author of django-secure, I do have one concern with the implementation plan: Django's existing validation checks are intended to be run in development, as a debugging aid, but not in production (to avoid any slowdown). Thus, by default they are run prior to many management commands (such as syncdb, runserver), but are generally not run on production deployments. The checks in django-secure, on the other hand, are intended to be run only under your production configuration, and are mostly useless/wrong in development. Since runserver doesn't handle HTTPS, most people don't use HTTPS in development, which means you can't set e.g. SESSION_COOKIE_SECURE to True in development or your sessions will break, which means that django-secure check will fail; same goes for most of the other checks. Running django-secure's checks every time you syncdb or runserver in development would be at best a waste of time and at worst extremely annoying. So I think the validation framework you build has to incorporate some kind of distinction between these two types of validation, which have very different purposes and should be run at different times: development/debugging validation and production-configuration validation. I'm not sure exactly what form this distinction should take: perhaps validators are simply tagged as one type or the other and then there are two different management commands? Interested in your thoughts, Carl -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not calling things twice in templates
We don't even have to change the for-syntax: {% for bee in my_bonnet.bees %} {% loop %} {{ bee }} {% endloop %} {% empty %} No bees! {% endfor %} Le mardi 4 juin 2013 00:03:12 UTC+2, Shai Berger a écrit : > > > {% for my_bonnet.bees %} > > {% each bee %} > {{ bee }} > {% endeach %} > > {% empty %} > No bees! > {% endfor %} > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Make sure QuerySet.get() does not fetch more rows than it absolutely needs
On 4 kesä, 00:22, Shai Berger wrote: > On Monday 03 June 2013, Patryk Zawadzki wrote: > > > Here's the ticket: > > >https://code.djangoproject.com/ticket/6785 > > > tl;dr: Calling .get() on a badly filtered queryset can result in lots > > of database rows being fetched and wrapped in Python objects for no > > gain. > > tl;dr: There's a general, valuable optimization to be made here, but it should > be implemented at a lower level. > > I have raised a related issue about a year and a half ago[0], thinking > (mistakenly) that it was mostly an Oracle issue. Ian Kelly had pointed me in > the right direction, but then life happened... The problem is that for all > single-row queries except aggregates, Django uses the same strategy as used in > get (and which you kept using in your patch): limit the query (usually) > properly, then fetch until no more records are retrieved (fetching in done in > chunks using fetchmany(), and not using fetchall()). > > For single-row queries, this means two fetches; an unnecessary network > roundtrip, for each such query, unless the backend or underlying driver take > care to prevent it. On Oracle, at least, nobody does. > > What we should do instead, in my opinion, is stop fetching as soon as a chunk > arrives that isn't full. This alone should reduce the number of network > accesses significantly on most Django projects. > > While we're doing that, we could also define a new mode of sql execution (see > SQLCompiler.results_iter(), in django.db.models.sql.compiler): Next to the > current SINGLE (which uses fetchone()) and MULTI (the chunked loop described > above) we could have SINGLE_VERIFY, which always fetches a single chunk of > size 2. Make get() use that, and #6785 is fixed, while improving performance > -- > rather than hurting it on correct usage, like the proposed patch[1] does. > > Assuming nobody raises objections, I intend to propose a patch along these > lines sometime in the coming weeks (it's one of a few things on my to-do > list), but I wouldn't mind at all if someone beat me to it. > > Hope this helps, > Shai. > > [0]https://groups.google.com/d/msg/django-developers/SQ0Pltt_f0M/3ccQn0a... > [1]https://github.com/django/django/pull/1139 Note that how queryset iteration happens has been changed[1]. Except for .iterator() call the rows in the queryset are converted to objects immediately. This isn't a big change for other core backends than Oracle (they always fetched all rows in one go), but for Oracle users this could mean changes in amount of rows fetched from DB. So, with this in mind you could change the compiler's iterator to use fetchall() except when .iterator() is used. As for .get() - I don't find the number of duplicates in the error message that useful. If you got more than one object you failed. How badly you failed isn't interesting. I can't think of any case where the amount of objects you got actually matters. If somebody feels strongly about this, then we could limit the amount of fetched objects to some smallish amount (21 for example). If you actually get 21 objects back then you say "it returned more than 20" in the error message. - Anssi [1]https://code.djangoproject.com/ticket/18702 -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.