2017-05-13 2 views
1

django.contrib.auth.models.Userには、first_namelast_nameフィールドの両方にblank=Trueがあります。自分のモデルでどうすればblank=False, null=Falseにすることができますか?ここでDjangoでfirst_nameとlast_nameを要求するユーザモデル

は基本的にExtending the existing User modelの指示に従って、私の実装です:python manage.py shellでテストするとき

models.py

class Fellow(models.Model): 

    user = models.OneToOneField(
     User, 
     on_delete=models.CASCADE 
    ) 

    first_name = models.CharField(
     _("first_name"), 
     max_length=30, 
    ) 
    last_name = models.CharField(
     _("last_name"), 
     max_length=30, 
    ) 

    # other fields omitted 

from . import signals 

signals.py

from django.contrib.auth.models import User 
from django.db.models.signals import post_save 
from django.dispatch import receiver 

from .models import Fellow 


@receiver(post_save, sender=User) 
def create_fellow_on_user_create(sender, instance, created, **kwargs): 
    if created: 
     Fellow.objects.create(user=instance) 

しかし、私はエラーを得た:

>>> f = Fellow.objects.create(username='username', password='passwd') 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method 
    return getattr(self.get_queryset(), name)(*args, **kwargs) 
    File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/db/models/query.py", line 392, in create 
    obj = self.model(**kwargs) 
    File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/db/models/base.py", line 571, in __init__ 
    raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0]) 
TypeError: 'username' is an invalid keyword argument for this function 
+0

元のUserクラスからモデルを派生させる必要があります。 @KlausD。 –

+0

あなたは 'User'を直接サブクラス化するのですか?しかし、ドキュメントのサンプルコードでは 'class Employee(User):'の代わりに 'class Employee(models.Model):'と書かれています... –

+0

@KlausD。 'django.core.exceptions.FieldError: 'Fellow'クラスのローカルフィールド 'first_name'が、基本クラス 'User'と同じ名前のフィールドと衝突します.' –

答えて

1

あなたはチュートリアルを誤解している:Userモデルが作成されていないとFellowインスタンスを開始するための正しい方法は次のようになりますので、あなたが得る
エラーが発生します。あなたが参照している従業員の例では、Userに追加する方法について説明しています。これは元のUserモデルを元のままにしたOneToOneFieldによって行われますが、実際の目的ではUserにはdepartmentという新しいフィールドがあるようです。これは、データベースに2つの別個のテーブルを作成することによって実装されます。

あなたが直接あなたが最初Userのインスタンスを作成せずにしようとした方法で新しいインスタンスを作成することはできませんEmployeeFellowに1つの警告は、あります。これは、どちらのモデルもユーザー名フィールドを直接所有していないためです。これは2つのステップで行います。しかし、この方法は依然として望ましいものではありません。両方のモデルにfirst_nameフィールドとlast_nameフィールドがあります。それは常に混乱につながります。適切な方法はAbstractBaseUser

class Fellow(AbstractBaseUser): 

    first_name = models.CharField(max_length=254) 

AbstractBaseUserをサブクラス化することである(コード参照:https://github.com/django/django/blob/master/django/contrib/auth/base_user.py#L47)を裸の骨ユーザーであるあなたが望む行動でそれらを追加することができますので、それはFIRST_NAMEとLAST_NAMEを持っていません。

0

v

1)AbstractBaseUserからあなたのUserクラスを派生し、必要なすべての定義:あなたが参照しているドキュメントのERY最初の行は、私はここに3つのオプションが表示さ

を代入せずにキーワードがある

There are two ways to extend the default User model without substituting your own model

語りますフィールド。あなたは例としてAbstractUserを取ることができます。

2)ユーザーセーブモデルのUserSerializerまたはpre_save信号に検証を追加し、first_nameおよびlast_nameフィールドを検証します。最も簡単な方法ですが、長期的なプロジェクトには適していません。

3)Userモデルへの参照をuserとして追加して、選択した方法で行ってください。 first_namelast_nameを定義しますが、Fellow.first_nameFellow.user.first_nameの間にこれらのフィールドが重複しないようにしてください。他の開発者がこのアイデアを誤解する可能性があるため、これは難しいかもしれません。

user = User.objects.create(username='test', email='[email protected]') 
fellow = Fellow.objects.create(user=user, first_name='firstname', last_name='last_name') 
関連する問題