Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

方針

  • あるモデルに 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>

hidelafoglia
コンピュータプログラミング勉強中です。
https://github.com/hdknr/note
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away