LoginSignup
0
0

More than 5 years have passed since last update.

Django: モデルフィールドのプライバシー制御を設定する

Posted at

方針

  • あるモデルに OneToOneでプライバシー制御を設定するモデルを定義する
  • プライバシー制御モデルは元のモデルと同じフィールド名とする
  • プライバシー制御モデルは動的に定義する

元モデル:個人属性(Profile)

  • 抽象モデル

class AbstractProfile(models.Model):
    user = models.OneToOneField(User)
    age = models.IntegerField()
    gender = models.IntegerField(choices=((0, 'Femail', ), (1, 'Male', ), ))

    class Meta:
        abstract = True
  • 具体モデル
class Profile(AbstractProfile):                                                     
    pass   

モデルに対してプライバシー制御モデルのフィールドを生成

  • 抽象モデルのフィールドを返す
def create_privacy_fields(model_class, field_class, **kwargs):    
    # メタクラスを abstract = Trueで作る                                               
    fields = {
        '__module__': model_class.__module__,
        'Meta': type('Meta', (object, ), {'abstract': True, }),
    }

    for i in model_class._meta.fields:
        if isinstance(i, models.AutoField):
            continue
        fields[i.name] = field_class(i.verbose_name, **kwargs)

    return fields

プライバシ制御モデル(ProfilePrivacy)

  • 抽象モデルをAbstractProfileを元に動的に生成
AbstractProfilePrivacy = type(
    'AbstractProfilePrivacy',
    (models.Model,),
    create_privacy_fields(
        AbstractProfile, models.BooleanField, default=False),
)   
  • 具体モデル: Profile <-(OneToOne)- ProfilePrivacy
class ProfilePrivacy(AbstractProfilePrivacy):
    profile = models.OneToOneField(Profile)

マイグレーション

$ python manage.py makemigrations accounts

Migrations for 'accounts':
  0001_initial.py:
    - Create model Profile
    - Create model ProfilePrivacy
$ python manage.py migrate

Operations to perform:
  Apply all migrations: accounts
Running migrations:
  Rendering model states... DONE
  Applying accounts.0001_initial... OK
$ python manage.py shell
In [1]: from django.contrib.auth.models import *
In [2]: from accounts.models import *
In [3]: u = User.objects.get(username='admin')
In [4]: p = Profile.objects.create(user=u, age=33, gender=0)
In [5]: pr = ProfilePrivacy.objects.create(profile=p)
In [6]: u.profile.profileprivacy.gender
Out[6]: False
In [7]: pr.gender = True
In [8]: pr.save()
In [9]: u.profile.profileprivacy.gender
Out[9]: True

テンプレート


<td>{% if request.user == profile.user or profile.profileprivacy.age %}
    {{ profile.age }} {% else %} 公開されていません {% endif %}</td>

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0