<commit_before>django-daydreamer
=================

A Django class-based view utility library.

### Quickstart

Install django-daydreamer with pip.

```
pip install django-daydreamer
```

Do stuff like this:

```python
from daydreamer.core import urlresolvers
from daydreamer.views import decorated, generic


class SpookyProtectedResourceView(decorated.AuthRequired, generic.TemplateView):
    template_name = "resources/detail.html"
    
    login_required = True
    
    active_required = True
    active_required_message = "Your account has been deactivated."
    active_required_redirect_url = urlresolvers.reverse_lazy("users:deactivated")
    
    permissions_required = "resources.resource_read"
    permissions_required_raise = True
    
    def test_required(self):
        return self.requst.user.is_spooky()
    test_required_message = "Join the Spooky program."
    test_required_redirect_url = urlresolvers.reverse_lazy("users:spooky_signup")
    
    def get_context_data(self, **context):
        # Retrieve the protected resource.
        # ...
```

The resulting view will perform a sequence of authentication checks before its
`get()` method is called:

* checks if the user is logged in, redirecting to the login page upon
    failure, just like Django's `@login_required` decorator.
* checks if the user's account is active, redirecting to the deactivated
    user information page and messaging the user about the account status
    upon failure.
* checks if the user has one or more permissions, raising a
    `PermissionDenied` exception on failure.
* checks if the user satisfies a test predirect, redirecting to the
    Spooky signup page and messaging the user about the
    Spooky program upon failure.

Of course, you won't want to repeat all of these attributes on your view
classes, so set up a few base classes that provide the common behaviors you
need and inherit from them throughout your view codebase.

For all of the view decorator mixins defined in
`daydreamer.views.decorated.auth` (import accessible at
`daydreamer.views.decorated`), you can control the inherited behavior through
a consistent set of attributes. The attributes are prefixed to match their
class names, except that they use lowercase-underscore casing instead of 
capital-camel casing. The optional values are:

* `<prefix>_raise` whether an exception should be raised upon test failure
* `<prefix>_exception` a custom exception to be raised upon test failure,
    defaults to `PermissionDenied`
* `<prefix>_message` a message to be enqueued upon test failure
* `<prefix>_message_level` the message's level, defaults to `WARNING`
* `<prefix>_message_tags` the message's tags, defaults to `""`
* `<prefix>_redirect_url` the URL to redirect to upon test failure,
    defaults to `settings.LOGIN_URL`
* `<prefix>_redirect_next_url` the return URL value to add to the redirect
    URL's query string, defaulting to the request's absolute URI.
* `<prefix>_redirect_next_name` the return URL parameter name to add to the
    redirect URL's query string, defaulting to REDIRECT_FIELD_NAME. If set to
    a falsy value, no return URL query parameter will be included in the
    redirect URL.

You can also find some cool things in `daydreamer.test`, like
`daydreamer.test.views.TestCase`, which lets you test a view class using the
full Django handler stack, without any need for a urls.py configuration.

More stuff is on the way.

### Status

This project now provides some useful and well-tested tools for writing
class-based views, so I've released the first version. At this point, you will
need to read the documentation found in the source code to figure out what's
possible. More documentation will be published once all planned view decorator
mixins have been fleshed out.
<commit_msg>Documentation updates.<commit_after>django-daydreamer
=================

A Django class-based view utility library.

### Quickstart

Install django-daydreamer with pip.

```
pip install django-daydreamer
```

Do stuff like this:

```python
from daydreamer.core import urlresolvers
from daydreamer.views import decorated, generic


class SpookyProtectedResourceView(decorated.AuthRequired, generic.TemplateView):
    template_name = "resources/detail.html"
    
    login_required = True
    
    active_required = True
    active_required_message = "Your account has been deactivated."
    active_required_redirect_url = urlresolvers.reverse_lazy("users:deactivated")
    
    permissions_required = "resources.resource_read"
    permissions_required_raise = True
    
    def test_required(self):
        return self.requst.user.is_spooky()
    test_required_message = "Join the Spooky program."
    test_required_redirect_url = urlresolvers.reverse_lazy("users:spooky_signup")
    
    def get_context_data(self, **context):
        # Retrieve the protected resource.
        # ...
```

The resulting view will perform a sequence of authentication checks before its
`get()` method is called:

* checks if the user is logged in, redirecting to the login page upon
    failure, just like Django's `@login_required` decorator
* checks if the user's account is active, redirecting to the deactivated
    user information page and messaging the user about the account status
    upon failure
* checks if the user has one or more permissions, raising a
    `PermissionDenied` exception on failure
* checks if the user satisfies a test predirect, redirecting to the
    Spooky signup page and messaging the user about the
    Spooky program upon failure

Of course, you won't want to repeat all of these attributes on your view
classes, so set up a few base classes that provide the common behaviors you
need and inherit from them throughout your view codebase.

The behavior of all the authentication view decorator mixins defined in
`daydreamer.views.decorated.auth` (import accessible at
`daydreamer.views.decorated`) can be controlled with a consistently-named
set of inherited attributes. The attributes are prefixed to match their
class names, except that they use lowercase-underscore casing instead of 
capital-camel casing. The optional values are:

* `<prefix>_raise` whether an exception should be raised upon test failure
* `<prefix>_exception` a custom exception to be raised upon test failure,
    defaults to `PermissionDenied`
* `<prefix>_message` a message to be enqueued upon test failure
* `<prefix>_message_level` the message's level, defaults to `WARNING`
* `<prefix>_message_tags` the message's tags, defaults to `""`
* `<prefix>_redirect_url` the URL to redirect to upon test failure,
    defaults to `settings.LOGIN_URL`
* `<prefix>_redirect_next_url` the return URL value to add to the redirect
    URL's query string, defaulting to the request's fully-qualified URL.
* `<prefix>_redirect_next_name` the return URL parameter name to add to the
    redirect URL's query string, defaulting to `"next"`. If set to
    a falsy value, no return URL query parameter will be included in the
    redirect URL.

All the views in `daydreamer.views.generic`, which mirrors Django's
`django.views.generic` package, provide helpful shortcuts. These are:

* `reverse()` reverses a named URL pattern, taking an optional `qualified`
    argument, which when truthy, will return a fully-qualified reversed URL
* `attachment()` returns an attachment response
* `redirect()` redirects to a named URL pattern
* `gone()` returns a 410 gone response
* `not_found()` raises the 404 response exception
* `permission_denied()` raises the 403 response exception
* `suspicious_operation()` raises the 400 response exception

You can also find some cool things in `daydreamer.test`, like
`daydreamer.test.views.TestCase`, which lets you test a view class using the
full Django handler stack, without any need for a urls.py configuration.

More stuff is on the way.

### Status

This project now provides some useful and well-tested tools for writing
class-based views, so I've released the first version. At this point, you will
need to read the documentation found in the source code to figure out what's
possible. More documentation will be published once all planned view decorator
mixins have been fleshed out.

{'fraction_non_alphanumeric': 0.06633337397878307, 'fraction_numerical': 0.0014632361907084503, 'mean_word_length': 4.508394895903291, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3449628', 'n_tokens_mistral': 2241, 'n_tokens_neox': 2133, 'n_words': 982}