Re: Allowing custom attributes in Meta classes
On Sep 10, 2013, at 7:05 PM, Russell Keith-Mageewrote: > I share James' reservations about this as a feature -- attaching flags to > Meta is something I can see being abused in all sorts of ways -- but that > doesn't mean there's no legitimate uses for extensions to Meta. For example, > the USERNAME_FIELD added in support of custom users should, arguably, be a > Meta option -- but there was no way we could add that without making a Meta > option available to every class. For what it's worth, I've loosely copied Django's "metaclass w/ Meta options" pattern for several projects. In cases where I needed a bit more flexibility, the metaclass looked for a well named attribute on the class that would specify the options class to use. For example: class Model(object): # _meta is a ModelOptions instance __OPTIONS_CLASS__ = ModelOptions class Foo(Model): # _meta is a ModelOptions instance, inheriting Model's __OPTION_CLASS__ class User(Model): # _meta is a UserModelOptions instance that looks # for a USERNAME_FIELD option __OPTIONS_CLASS__ = UserModelOptions -- 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. For more options, visit https://groups.google.com/groups/opt_out.
Re: pre_init/post_init vs. performance
On Jul 14, 2012, at 6:37 PM, Russell Keith-Magee wrote: > > My only concern is: > >> We could store which fields have these hooks upon ModelBase.__new__ >> construction and so skip most fields and overhead in __init__. > > I'm not sure if I'm misreading your intentions here, but just to be > sure -- I'd like to avoid explicitly naming certain field types as > "special" in ModelBase if at all possible. If we explicitly name > certain fields in ModelBase, then it means that third-parties with the > same requirement won't be able to exploit the same API entry point. In > the case of GenericForeignKey specifically, it also means that we > would be introducing a dependency (even if it was name-only) on > contrib into core -- which is something we've been trying to move away > from. I think Jeremy means doing something like this in ModelBase.__new__: meta.fields_needing_init = [field for field in fields if hasattr(field, 'model_pre_init')] And in ModelBase.__init__: for field in self._meta.fields_needing_init: field.model_pre_init(*args, **kwargs) This way, in ModelBase.__init__, only the fields that actually need to be initialized have this method called. -andy -- 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: Smart extends
We are in complete agreement ;) 2010/10/15 J. Pablo Martín Cobos <goi...@gmail.com> > Hi Andrew, > > I think you agree with me in all. Thank you very much for your long e-mail. > I think you have explain the problem better than me. To use the urls for > overwrite the templates "leads terrible looking URL", it's really true. > > If you don't think you agree with me in all, please tell me. Because as my > english is not very good I don't know if I have understand you perfect. > > -- > Pablo Martín > > 2010/10/15 Andy McCurdy <sed...@gmail.com> > >> >> On Fri, Oct 15, 2010 at 6:09 AM, Andrew Godwin <and...@aeracode.org>wrote: >> >>> So, from what I can work out, this is a proposal for an {% extends %} tag >>> which allows you to extend from the parent template of the same name (so it >>> looks back in the list of possible templates, and picks the one that comes >>> before yours, in your case inheriting from the admin version of the template >>> with the same name? >>> >>> I'd like to know what sort of use cases you think this is necessary in - >>> in the example you provide, admin/change_list.html, the recommended way of >>> doing what you're doing would be to set change_list_template on the >>> ModelAdmin class to point to a different template which itself inherits from >>> admin/change_list.html, rather than having two with the same name, which >>> could be potentially confusing. >> >> >> At Whiskey, we have a custom extends tag that accomplishes the same thing >> -- the ability to extend templates of the same name. For a quick background, >> we have a fairly large number of apps that we reuse on multiple sites. Each >> app provides a set of templates with "sane default" functionality. We end up >> customizing a fair number of these templates on a per-site basis to simply >> add some additional context for users. For example, we have a generic forum >> app. On our video game site, we've added our users' XBOX Live scores under >> their usernames when displaying forum messages. This gives viewers an idea >> how much the author actually knows about the game being discussed. We do >> these kinds of things quite frequently. >> >> We've named our custom extends tag "extends" and simply add it to the >> system builtins. This way, all template extending goes through our tag. >> >> We chose to use this custom extends method rather than the established >> "have your view accept a template parameter, then manually specify the >> template from the urls.py module" pattern for several reasons: >> >> - We found having more template names was more confusing. Across all of >> our apps, we already have close to 1,000 unique template names. Adding more >> for these common customizations would lead to more confusion of our >> designers. >> >> - Specifying overridden templates in urls.py leads to terrible looking URL >> files. It's also a gross violation of DRY. Consider this example: >> >> forums/urls.py: >> -- >> ... >> url(r'topic/$', views.topic, name='forum-topic'), >> ... >> >> site/urls.py >> -- >> ... >> (r'fourms/$', include('forums.urls')), >> ... >> >> Now if I want to override the template that displays a forum topic, I have >> to not only include the forums.urls above, I also have to copy/paste the >> forum-topic url into site/urls.py to simply add extra kwargs specifying the >> template name to the view. This gets gross real quick: >> >> site/urls.py >> -- >> ... >> from forums import views >> url(r'forums/topic/$', forum_views.topic, name='forum-topic', >> kwargs={'template': 'overridden_template.html'}), >> (r'fourms/$', include('forums.urls')), >> ... >> >> >> - One or two of the 3rd party apps we use don't allow for template >> customize through view kwargs. Since our tag is loaded as the default >> extends tag, we can customize these templates for free without having to >> write any Python code. >> >> - Finally, I don't really want our designers in Python code if I can help >> it. Even if it's just copy/pasting from one urls file to another. And I >> certainly don't want to be asked every time they want to override a template >> to make a 1 line change. >> >> -andy >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django developers" group. >> T
Re: Smart extends
2010/10/15 Łukasz Rekucki> 2010/10/15 J. Pablo Martín Cobos : > > > > Really the problem comes when we reuse a application: from other people, > > from Django (i.e. django.contrib.admin), or even my own that we reuse in > > some projects. Usually you want to change slight things and usually you > want > > only to change the visualization mode, you want to change the templates. > You > > need to adapt the application to your project. > > > > It's a pretty good use case. But there's a problem with your original > proposal: the admin provides a default "x.html" . Then you have some > 3rd party application "A" that enhances the "x.html". And now comes > your application "B" that also wants to extend "x.html". So you write: > > {% extends "x.html" %} > > Which "x.html" should be chosen ? the one from admin or the one from > external app "A" ? Both are valid uses. There is a dangerous > temptation to say "next that would be loaded after this", but that > depends on loaders and application order - lets don't go that way. > > Instead, IMHO, a good way to do this would be verbose about from which > application you want the template to be loaded: > > {% extends admin:"x.html" %} # extend x.html from admin > {% extends A:"x.html" %} # extend x.html from application A > > Unfortunately for this approach, templates aren't provided or bound to > applications - they're provided by loaders. It might be a good idea to > extend the loader protocol to me "namespace" aware. > > My 2cents. > > Ya, if you're using the AppDirectory loader already, you get this for free. Of course if Django were to accept this, it would need to work with all the loaders. For our implementation, we've made our own template loader subclasses the AppDirectory one. -andy -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@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: Smart extends
On Fri, Oct 15, 2010 at 6:09 AM, Andrew Godwinwrote: > So, from what I can work out, this is a proposal for an {% extends %} tag > which allows you to extend from the parent template of the same name (so it > looks back in the list of possible templates, and picks the one that comes > before yours, in your case inheriting from the admin version of the template > with the same name? > > I'd like to know what sort of use cases you think this is necessary in - in > the example you provide, admin/change_list.html, the recommended way of > doing what you're doing would be to set change_list_template on the > ModelAdmin class to point to a different template which itself inherits from > admin/change_list.html, rather than having two with the same name, which > could be potentially confusing. At Whiskey, we have a custom extends tag that accomplishes the same thing -- the ability to extend templates of the same name. For a quick background, we have a fairly large number of apps that we reuse on multiple sites. Each app provides a set of templates with "sane default" functionality. We end up customizing a fair number of these templates on a per-site basis to simply add some additional context for users. For example, we have a generic forum app. On our video game site, we've added our users' XBOX Live scores under their usernames when displaying forum messages. This gives viewers an idea how much the author actually knows about the game being discussed. We do these kinds of things quite frequently. We've named our custom extends tag "extends" and simply add it to the system builtins. This way, all template extending goes through our tag. We chose to use this custom extends method rather than the established "have your view accept a template parameter, then manually specify the template from the urls.py module" pattern for several reasons: - We found having more template names was more confusing. Across all of our apps, we already have close to 1,000 unique template names. Adding more for these common customizations would lead to more confusion of our designers. - Specifying overridden templates in urls.py leads to terrible looking URL files. It's also a gross violation of DRY. Consider this example: forums/urls.py: -- ... url(r'topic/$', views.topic, name='forum-topic'), ... site/urls.py -- ... (r'fourms/$', include('forums.urls')), ... Now if I want to override the template that displays a forum topic, I have to not only include the forums.urls above, I also have to copy/paste the forum-topic url into site/urls.py to simply add extra kwargs specifying the template name to the view. This gets gross real quick: site/urls.py -- ... from forums import views url(r'forums/topic/$', forum_views.topic, name='forum-topic', kwargs={'template': 'overridden_template.html'}), (r'fourms/$', include('forums.urls')), ... - One or two of the 3rd party apps we use don't allow for template customize through view kwargs. Since our tag is loaded as the default extends tag, we can customize these templates for free without having to write any Python code. - Finally, I don't really want our designers in Python code if I can help it. Even if it's just copy/pasting from one urls file to another. And I certainly don't want to be asked every time they want to override a template to make a 1 line change. -andy -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@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: #12012 Logging: Final call for comments
Russ, This will be a welcomed addition to debugging Django apps. I have a question about startup.py. I notice that startup runs after settings are loaded, but before models. Does this mean that code within startup.py cannot safely access the ORM? If the ORM is fully accessible in startup.py, it's safe to ignore the rest of the mail. If I cannot access models from startup.py, I have two concerns: 1. It seems fairly limiting. We currently have a hacked together startup system for several ORM-related tasks. I'd love to replace this with yours, assuming I don't lose functionality. Most notable, we have configuration stored in the DB that is used to determine application behavior. Another use case is using the startup system to add some of our template tags libraries to builtins. Some of these template tag libs import models. Would this end up causing circular reference issues? We used to have these kinds of tasks load on the first request Django processed using the request_started signal. However, this was limiting because management commands and celery tasks never received the signal. We need a system where no matter how our Django is loaded, startup happens. 2. What kind of error message am I going to receive if I do access models? Debugging circular references is quite painful. At the very least, we should consider a user trying to import models (or something else that imports models) a common error and attempt to present a concise error message. -andy On Thu, Sep 30, 2010 at 6:56 AM, Russell Keith-Magee < russ...@keith-magee.com> wrote: > Hi all, > > A final call for comment before I commit #12012 to trunk. Barring > objection, my intention is to commit this early next week. > > I've integrated the suggestions that have arisen since the first draft: > > * This patch has docs :-) There aren't any tests though, and I think > it's going to have to stay that way; this is one of those areas where > it's almost impossible to test because it's very difficult to mock out > early stages of app configuration. The good news is that the complex > logic is all contained inside Python's logging library itself, and the > logging calls that have been introduced are all exercised as part of a > normal test run. > > * I've modified the interpretation of LOGGING_CONFIG such that a > value of None means "don't configure logging" > > * I've modified the global-settings and project template logging > settings. They are now at parity. > > * I've modified the logging information that is provided in the 4XX > loggers so that a status code is provided as logging context. 4XX > messages are all still logged as warnings, but if you want to change > this, you now have enough detail in the log record to use a log filter > for that purpose. > > If you have any objections, now is the time to raise them. > > Yours, > Russ Magee %-) > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-develop...@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. > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@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: logialogin_required does not check User.is_active
On Thu, Apr 15, 2010 at 9:50 AM, Harrowrote: > I think the problem isn't the login_required, but it simply does what > it says it does: Check if the user is logged in. > > For me a user with is_active set to false shouldn't be allowed to > login, they either just created an account and still need to verify it > or they indicated that they wanted their account "removed", in which > case it's marked inactive so it doesn't cascade delete all their > related items too. > Or the third case, when a staff user de-activates the user for some reason. In this scenario, the user is still logged in, and simply using @login_required will continue to allow the user to access resources that are meant to be restricted. To correct this behavior, we've subclassed the Authentication middleware and the LazyUser object it sets on the request. Our LazyUser ensures the user is active, otherwise it creates an AnonymousUser instance. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@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.
post_delete signal is sent when no objects are deleted
If two different threads have a reference to a single model instance, both can call the instance's delete() method. Only one of the threads will perform the actual deletion from the database, but both will send a post_delete signal. This can cause a number of race conditions with signal handlers connected to post_delete. A fairly common pattern for a signal handler it to perform an action such as: === class Foo(models.Model): count_of_bars = models.IntegerField() class Bar(models.Model): foo = models.ForeignKey(Foo) def update_bar_count(sender, instance, **kwargs): instance.foo.count_of_bars -= 1 instance.foo.save() models.signals.post_delete.connect(update_bar_count, Bar) === In this case, if the same Bar instance is deleted by two different threads, the "count_of_bars" column on the corresponding Foo record will be off by 1 To solve this, the affected row count would need to be examined after a delete query, which indicates whether the object was deleted by this thread. If the affected row count is 1, then we know the current thread performed the deletion and should be responsible for sending the post_delete signal. If the affected row count is 0, then the object was deleted by another thread, and the current thread should *not* send a post_delete signal. Unfortunately, there's another complexity. Calling delete() on a model instance also deletes records from other models that are foreign keyed to the record being deleted. (In the above example, if a Foo is deleted, all the related Bars are also deleted.) The django.db.models.query.delete_objects function is optimized to perform these deletes in batches using an IN() query. This implementation makes it impossible to determine which rows the current thread actually deleted anytime the affected row count is less than the number of rows requested to be deleted. This could be corrected by changing delete_objects, making it execute a separate delete query for each object being deleted. While this would not be as efficient, it seems like the only way to correctly send post_delete signals. I've started working on a patch/tests that implements the above solution. I'd like to get thoughts from others about this issue and the proposed solution prior to making a new ticket. Thanks, -andy --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---