Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 249
Rivadiz Avatar asked Feb 18 '17 13:02

Rivadiz


1 Answers

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.

like image 153
Rivadiz Avatar answered Sep 22 '22 10:09

Rivadiz