Usage :
class MyModelAdmin(ReadonlyLinksMixin, admin.ModelAdmin):
readonly_fields_links = ('field1', 'field2')
This adds a new ModelAdmin property (`readonly_fields_links`) that acts like the default `readonly_links` except that (if the field's type is a model that can be edited in the admin site) the value of the field has a link to the object.
Same functionality as
* [This snippet](https://www.djangosnippets.org/snippets/937/)
* [and this one](https://www.djangosnippets.org/snippets/1008/)
Except that it works without messing with the form that gets validated and saved, and thus without sometimes saving None values. It uses the documented property that `readonly_fields` can be callables ([Django doc](https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display)) : the fields in `readonly_links_fields` are turned into callables that are appended to `readonly_links`. Each callable creates the linked value.
If you require lots of forms in your project and do not want to be creating an extended template for each one I propose this solution.
Classes in the html correspond to bootstrap, you can work without them if you do not use bootstrap.
Hyperlinks to views requiring authentication in Microsoft Office (Word, Excel, Powerpoint) can fail based on how Office handles rendering. This middleware sends a refresh return to the client, which will allow the page to be opened as normal, instead of the "Unable to open ... Cannot download the information you requested."
This is a port from the ruby middleware project [fix microsoft links](https://github.com/spilliton/fix_microsoft_links).
To enable, add to your [middleware stack](https://docs.djangoproject.com/en/dev/topics/http/middleware/) in the django project settings.
Inspired by [Base64Field: base64 encoding field for storing binary data in Django TextFields](https://djangosnippets.org/snippets/1669/) but in a generic way.
from django.db import models
import base64
class Base64Encryptor(object):
def encrypt(self, value):
return base64.encodestring(value)
def decrypt(self, msg):
return base64.decodestring(msg)
class MyModel(models.Model):
...
b64_data = EncryptedField(encryptor=Base64Encryptor)
...
# Usage
my_obj = MyModel()
my_obj.b64_data = "hello"
print(my_obj.b64_data) # will output 'hello'
print(my_obj.b64_data_enc) # will output 'aGVsbG8=\n'
Use this template tag to get a paginator showing the first and last two pages w/ adjacent pages using ellipsis.
The `page` parameter is a page of a `Paginator` (typically the first but you can use whichever you want).
In case of 50 pages, while being on the 40th, it'll give you the following iterable of `int`s (with `settings.PAGINATOR_ADJACENT_PAGES = 2`):
`(1, 2, 38, 39, 40, 41, 42, 49, 50) `
You get the idea.
The idea here is to wrap the original `delete_selected` functionality in a way that I shouldn't have to reimplement the templates (confirmation/error response) serving, just extend the original.
What this code does, it wraps the queryset's delete function with a closure, so when it really gets called (after the confirmation), it executes the extra functionality you wish to.
After looking at the original code, this seemed to be the most efficient way of doing it.
What the docstring says. To not use some functionality, e.g. managing the value in the User's Profile model, delete the corresponding lines (when getting the page_size and when saving it.
Add the Mixin before the View class. e.g.: `class ItemList(PaginationMixin, generic.ListView):`
I needed to make appcache for my application which used django-compress for JS and CSS compression. This is, how I solved the problem with putting compressed files into the manifest.
I went for offline compression (with `COMPRESS_OFFLINE=True`). This snippet shows code of command file (put it in `apps/cyklomapa/management/commands/compress_create_manifest.py`), which creates `compress_cache_manifest.txt` file in my templates.
Then I just use `{% include "compress_cache_manifest.txt" %}` in my appcache template.
Wraps many Form subclases in order to get a form wizard to treat them as one.
Many Forms will use one step.
**Example:**
`class LanguageVerifiedHumanForm(MultipleForms):
base_forms = [
('language_form', LanguageForm), ('verified_human_form', VerifiedHumanForm)
]`
`class NewGuideWizard(SessionWizardView):
form_list = [
('guide_form', GuideForm),
('multi_form', LanguageVerifiedHumanForm),
]`
## How to use
Use this [admin filter](https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter) together with a numeric field to allow filtering changlist by field
values range (in this case, age groups):
For example, to group customers by age groups:
class Customer(models.Model):
# ...
age = models.IntegerField()
age.list_lookup_range = (
(None, _('All')),
([0, 2], '0-2'),
([2, 4], '2-4'),
([4, 18], '4-18'),
([18, 65], '18-65'),
([65, None], '65+'),
))
class CustomerAdmin(admin.ModelAdmin):
list_filter = [('age', ValueRangeFilter), ]
## Inspiration
[This snippet](https://djangosnippets.org/snippets/587/) (for django < 1.4) inspired me to make this work for newer django versions.
If using javascript is not an option, you can use something like this code to have a variable number of subforms.
This code uses crispy-forms, but it is totally dispensable.