Metadata-Version: 2.1
Name: proxyid
Version: 0.1.0
Summary: Proxyid hides your Django model primary key
Home-page: https://github.com/felipepaes/proxyid
Author: Felipe Paes
Author-email: felipepaes@disroot.org
License: FreeBSD License
Project-URL: Bug Tracker, https://github.com/felipepaes/proxyid/issues
Description: # Proxyid
        
        Proxyid hides your Django model primary key
        
        Proxyid turns **`https://myapp.com/model/1`** into **`https://myapp.com/model/5NxJD1dG6V`**
        
        It makes use of the [hashids library](https://hashids.org) to mask your integer or uuid based primary keys. It's plug'n play, therefore, it doesn't interfere with the database or model definitions.
        
        | Type    | Primary Key                              | Exposed Proxied PK           |
        | :------ | :--------------------------------------- | :--------------------------- |
        | Integer | 3                                        | 5NxJD1dG6VB3ZR3eKyzYEWrba    |
        | UUID    | 82df2e8e-553b-4330-bd46-8299ec67a9bb	 | 7ljjRD1qVLfjkQepdRZAimyDDZZ2 |
        
        
        ## Quick Start
        
        Assuming a Django project is already set with an app called appmock, proxyid can be installed with **pip**.
        
        ```terminal
        $ pip install proxyid
        ```
        
        The configuration is set as a constant `PROXYID` in `settings.py`
        
        ```python
        PROXYID = {
            "hashids": {
                "salt": "A grain of salt", # this is your salt
                "min_length": 15           # this is the minimum length of the proxied id
            }
        }
        ```
        
        Let's say the project has an Author model
        
        ```python
        # djangoproject/appmock/models.py
        from django.db import models
        
        class Author(models.Model):
            name = models.CharField()
            nationality = models.CharField()
        
            def __str__(self):
                return self.name
        ```
        
        Now take a look at our `urls.py`
        
        ```python
        # djangoproject/appmock/urls.py
        from django.urls import path
        from appmock import views
        
        
        urlpatterns = [
            # ...other path configuration
            # ...other path configuration
            # ...other path configuration
            path("author/<pk>/", views.author_detail, name="author-detail")
        ]
        ```
        
        ### Proxify the Primary Key
        
        If the app is exposing the database's primary key, the Author resource would be found, for example, at `http://myapp.com/author/1`
        Let's hide our primary key. by importing the `proxify` decorator and defining a property method.
        
        
        ```python
        # djangoproject/appmock/models.py
        from django.db import models
        from proxyid.decorators import proxify
        
        class Author(models.Model):
            name = models.CharField()
            nationality = models.CharField()
        
            @property
            @proxify
            def id_(self): pass
        
            def __str__(self):
                return self.name
        ```
        
        That's it, now our model instance will have the `id_` property with it's unique primary key encoded by proxyid by using the hashids library. All we need  is a method which doesn't return anything and the decorators `@property` and `@proxify`. You can name this property method whatever you want(except **pk** or **id**), let's name it `id_` for this example.
        
        Let's check it by retrieving a model in a django shell session
        
        ```terminal
        $ python manage.py shell
        Python 3.9.2 (default, Mar 21 2021, 20:35:03)
        [GCC 9.3.0] on linux
        Type "help", "copyright", "credits" or "license" for more information.
        (InteractiveConsole)
        >>> from appmock import models
        >>> author = models.Author.object.create(name="Lima Barreto", nationality="Brazil")
        >>> author.id
        1
        >>> author.id_
        RvBykxK6qojOJnOMrQeGpALDW
        ```
        
        ### Retrieving objects from encoded Primary Keys
        
        Now, how about retrieving our object from the database if our user is giving us the encoded(`RvBykxK6qojOJnOMrQeGpALDW`) primary key?
        Let's go to our hypothetical `author_detail` view function in `views.py`
        
        ```python
        # djangoprojects/appmock/views.py
        from django.shortcuts import render, HttpResponse
        
        from appmock.models import Author
        
        from proxyid.encoding import decode
        
        # ...other code
        
        def author_detail(request, pk):
            decoded_pk = decode(pk) # this will bring RvBykxK6qojOJnOMrQeGpALDW back to 1
            author = Author.objects.get(pk=decoded_pk)
            context = {"author" : author}
            return render(request, "appmock/author_detail.html", context)
        
        ```
        
        We imported `decode` from `proxyid.encoding`, the `decode` function will transform our proxied value back to it's original primary key value, allowing us to retrieve our object by giving the pk value to the ORM.
        
        How the urls were generated? By just passing the object `id_` instead of `pk` property or whatever name you have it to the url function. Like this:
        
        ```django-templates
        <!-- some html -->
        
        {% url 'author-detail' author.id_ %}
        ```
        
        Now our author resource can be found at `http:myapp.com/author/RvBykxK6qojOJnOMrQeGpALDW`
        
        ### What about class based views?
        
        Let's build the same logic of `author_detail` function view as a class based view now:
        
        ```python
        # djangoproject/appmock/views.py
        from django.views import generic
        
        from appmock.models import Author
        
        from proxyid.mixins import ProxyidMixin
        
        class AuthorDetailView(ProxyidMixin, generic.DetailView):
            template_name = "appmock/author_detail.html"
            model = Author
            context_object_name = "author"
        ```
        
        That's it, the view will work the same way as long as you use the `ProxyidMixin` as a parent class, and don't forget to provide a `pk` argument(this can be customized) from the url dispatcher.
        
Platform: UNKNOWN
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Framework :: Django :: 1.11
Classifier: Framework :: Django :: 2.0
Classifier: Framework :: Django :: 2.1
Classifier: Framework :: Django :: 2.2
Classifier: Framework :: Django :: 3.0
Classifier: Framework :: Django :: 3.1
Requires-Python: >=3.6
Description-Content-Type: text/markdown
