{"id":13469284,"url":"https://github.com/skorokithakis/django-annoying","last_synced_at":"2025-04-29T18:51:49.722Z","repository":{"id":39748968,"uuid":"7772867","full_name":"skorokithakis/django-annoying","owner":"skorokithakis","description":"A django application that tries to eliminate annoying things in the Django framework. ⛺","archived":false,"fork":false,"pushed_at":"2025-04-03T12:32:12.000Z","size":193,"stargazers_count":925,"open_issues_count":8,"forks_count":86,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-20T19:41:34.175Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://skorokithakis.github.io/django-annoying","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skorokithakis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.txt","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-01-23T10:50:54.000Z","updated_at":"2025-04-15T21:17:45.000Z","dependencies_parsed_at":"2024-10-30T13:02:40.207Z","dependency_job_id":"4a440fa0-8ed9-4f99-a41a-9c37413769e8","html_url":"https://github.com/skorokithakis/django-annoying","commit_stats":{"total_commits":184,"total_committers":47,"mean_commits":"3.9148936170212765","dds":0.7880434782608696,"last_synced_commit":"284fc3b2000106e4cb07adcbc355b48830084998"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skorokithakis%2Fdjango-annoying","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skorokithakis%2Fdjango-annoying/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skorokithakis%2Fdjango-annoying/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skorokithakis%2Fdjango-annoying/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skorokithakis","download_url":"https://codeload.github.com/skorokithakis/django-annoying/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251313979,"owners_count":21569529,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T15:01:31.876Z","updated_at":"2025-04-29T18:51:49.682Z","avatar_url":"https://github.com/skorokithakis.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"Description\n-----------\n\n[![Code Shelter](https://www.codeshelter.co/static/badges/badge-flat.svg)](https://www.codeshelter.co/)\n\nThis django application eliminates certain annoyances in the Django\nframework.\n\n### Features\n\n-   [render_to decorator](#render_to-decorator) - Reduce typing in django views.\n-   [signals decorator](#signals-decorator) - Allow using signals as decorators.\n-   [ajax_request decorator](#ajax_request-decorator) - Returns JsonResponse with dict as content.\n-   [autostrip decorator](#autostrip-decorator) - Strip form text fields before validation\n-   [get_object_or_None function](#get_object_or_none-function) - Similar to get_object_or_404, but returns None if the object is not found.\n-   [AutoOneToOne field](#autoonetoonefield) - Creates a related object on first call if it doesn't exist yet.\n-   [JSONField](#jsonfield) - A field that stores a Python object as JSON and retrieves it as a Python object.\n-   [get_config function](#get_config-function) - Get settings from django.conf if exists, return a default value otherwise.\n-   [StaticServer middleware](#staticserver-middleware) - Instead of configuring urls.py, just add\n    this middleware and it will serve your static files when you are in\n    debug mode.\n-   [get_ object_or_this_function](#get_object_or_this-function) - Similar to get_object_or_404, but returns a default object (`this`) if the object is not found.\n-   HttpResponseReload - Reload and stay on same page from where the request\n    was made.\n\n### Installation instructions\n\n-   Copy the `annoying` directory to your django project or put in on your PYTHONPATH.\n-   You can also run `python setup.py install`, `easy_install django-annoying`,\n    or `pip install django-annoying`.\n-   Add `\"annoying\"` under INSTALLED\\_APPS in your `settings.py` file.\n-   Django-annoying requires Django 1.11 or later.\n\nExamples\n--------\n\n### render_to decorator\n\n```python\nfrom annoying.decorators import render_to\n\n# 1. Template name in decorator parameters\n\n@render_to('template.html')\ndef foo(request):\n    bar = Bar.object.all()\n    return {'bar': bar}\n\n# equals to\ndef foo(request):\n    bar = Bar.object.all()\n    return render(request, 'template.html', {'bar': bar})\n\n\n# 2. Template name as TEMPLATE item value in return dictionary\n\n@render_to()\ndef foo(request, category):\n    template_name = '%s.html' % category\n    return {'bar': bar, 'TEMPLATE': template_name}\n\n#equals to\ndef foo(request, category):\n    template_name = '%s.html' % category\n    return render(request, template_name, {'bar': bar})\n```\n\n### signals decorator\n\nNote: `signals` is deprecated and will be removed in a future version. Django now [includes this by default](https://docs.djangoproject.com/en/stable/topics/signals/#connecting-receiver-functions).\n\n```python\nfrom annoying.decorators import signals\n\n# connect to registered signal\n@signals.post_save(sender=YourModel)\ndef sighandler(instance, **kwargs):\n    pass\n\n# connect to any signal\nsignals.register_signal(siginstance, signame) # and then as in example above\n\n#or\n\n@signals(siginstance, sender=YourModel)\ndef sighandler(instance, **kwargs):\n    pass\n\n#In any case defined function will remain as is, without any changes.\n```\n\n### ajax_request decorator\n\nThe `ajax_request` decorator converts a `dict` or `list` returned by a view to a JSON or YAML object,\ndepending on the HTTP `Accept` header (defaults to JSON, requires `PyYAML` if you want to accept YAML).\n\n```python\nfrom annoying.decorators import ajax_request\n\n@ajax_request\ndef my_view(request):\n    news = News.objects.all()\n    news_titles = [entry.title for entry in news]\n    return {'news_titles': news_titles}\n```\n\n### autostrip decorator\n\nNote: `autostrip` is deprecated and will be removed in a future version. Django now [includes this by default](https://docs.djangoproject.com/en/stable/ref/forms/fields/#django.forms.CharField.strip).\n\n```python\nfrom annoying.decorators import autostrip\n\n@autostrip\nclass PersonForm(forms.Form):\n    name = forms.CharField(min_length=2, max_length=10)\n    email = forms.EmailField()\n```\n\n### get_object_or_None function\n\n```python\nfrom annoying.functions import get_object_or_None\n\ndef get_user(request, user_id):\n    user = get_object_or_None(User, id=user_id)\n    if not user:\n        ...\n```\n\n### AutoOneToOneField\n\n```python\nfrom annoying.fields import AutoOneToOneField\n\n\nclass MyProfile(models.Model):\n    user = AutoOneToOneField(User, primary_key=True)\n    home_page = models.URLField(max_length=255, blank=True)\n    icq = models.IntegerField(blank=True, null=True)\n```\n\n### JSONField\n\nNote that if you're using Postgres you can use the built-in [django.contrib.postgres.fields.JSONField](https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/fields/#jsonfield), or if you're using\nMySQL/MariaDB you can use [Django-MySQL's JSONField](https://django-mysql.readthedocs.io/en/latest/model_fields/json_field.html).\n\n```python\nfrom annoying.fields import JSONField\n\n\n#model\nclass Page(models.Model):\n    data = JSONField(blank=True, null=True)\n\n\n\n# view or another place..\npage = Page.objects.get(pk=5)\npage.data = {'title': 'test', 'type': 3}\npage.save()\n```\n\n### get_config function\n\n```python\nfrom annoying.functions import get_config\n\nADMIN_EMAIL = get_config('ADMIN_EMAIL', 'default@email.com')\n```\n\n### StaticServer middleware\n\nAdd this middleware as first item in MIDDLEWARE\\_CLASSES(or MIDDLEWARE)\n\nexample:\n\n```python\nMIDDLEWARE_CLASSES = (  # MIDDLEWARE if you're using the new-style middleware\n    'annoying.middlewares.StaticServe',\n    'django.middleware.common.CommonMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.doc.XViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n)\n```\n\nIt will serve static files in debug mode. Also it helps when you debug\none of your middleware by responding to static requests before they get\nto debugged middleware and will save you from constantly typing \"continue\"\nin debugger.\n\n\n### get_object_or_this function\n\n```python\nfrom annoying.functions import get_object_or_this\n\ndef get_site(site_id):\n    base_site = Site.objects.get(id=1)\n\n    # Get site with site_id or return base site.\n    site = get_object_or_this(Site, base_site, id=site_id)\n\n    ...\n    ...\n    ...\n\n    return site\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskorokithakis%2Fdjango-annoying","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskorokithakis%2Fdjango-annoying","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskorokithakis%2Fdjango-annoying/lists"}