Search code examples
pythondjangopostgresqlprivacy

Django set privacy options per model field


I have gone through the question, best way to implement privacy on each field in model django and Its answers doesn't seem solve my problem so I am asking some what related question here,

well, I have a User model. I want the user to make possible to control the privacy of each and every field of their profile (may be gender, education, interests etc . ..).

The privacy options must not to be limited to just private or public, but as descriptive as

  • public
  • friends
  • only me
  • friend List 1 (User.friendlist.one)
  • friend List 2 (User.friendlist.two)
  • friend List 3 (User.friendlist.three)
  • another infinte lists that user may create.

I also don't want these privacy options to be saved on another model, but the same so that with one query I could get the user object along with the privacy options.

so If I have the UserModel,

class User(models.Model):
    name = models.CharField()
    email = models.EmailField()
    phone = models.CharField()

How do I setup a privacy setting here? I am using postgres, can I map a JSON field or Hstore even an ArrayField?

what is the best solution that people used to do with Django with same problem?

update:

I have n model fields. What I really want is to store the privacy settings of each instance on itself or some other convenient way.


Solution

  • I have worked on my issue, tried solutions with permissions and other relations. I have a Relationship Model and all other relationship lists are derived from the Relationship model, so I don't want to maintain a separate list of Relationships.

    So my pick was to go with a Postgres JSONField or HStoreField. Since Django has good support for postgres freatures, I found these points pro for the choice I made.

    • JSON/HashStore can be queried with Django ORM.
    • The configurations are plain JSON/HashStore which are easy to edit and maintain than permissions and relations.
    • I found database query time taken are larger with permissions than with JSON/HStore. (hits are higher with permissions)
    • Adding and validating permissions per field are complex than adding/validating JSON.
    • At some point in future if comes a more simple or hassle free solution, I can migrate to it having whole configuration at a single field.

    So My choice was to go with a configuration model.

    class UserConfiguration(models.Model):
        user = # link to the user model
        configuration = #either an HStore of JSONFeild
    

    Then wrote a validator to make sure configuration data model is not messed up while saving and updating. I grouped up the fields to minimize the validation fields. Then wrote a simple parser that takes the users and finds the relationship between them, then maps with the configuration to return the allowed field data (logged at 2-4ms in an unoptimized implementation, which is enough for now). (With permission's I would need a separate list of friends to be maintained and should update all the group permissions on updation of privacy configuration, then I still have to validate the permissions and process it, which may take lesser time than this, but for the cost of complex system).

    I think this method is scalable as well, as most of the processing is done in Python and database calls are cut down to the least as possible.

    Update

    I have skinned down database queries further. In the previous implementation the relations between users where iterated, which timed around 1-2ms, changing this implementation to .value_list('relations', flat=True) cut down the query time to 400-520µs.