2016-07-09 10 views
0

私はUserを拡張するクラスを持っているので、物理アドレスも格納できます。ModelFormでユーザーを拡張するクラスに書き込む方法

from django.contrib.auth.models import User 

class CustomUser(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    street = models.CharField(max_length=80, default="") 
    post_name = models.CharField(max_length=80, default=None) 
    post_number = models.IntegerField(default=None) 

のSQLiteデータベース内のモデルは、列を保持:views.py Iで

class BasicUserSettingsForm(forms.ModelForm): 
    class Meta: 
     model = User 
     fields = ['first_name', 'last_name', 'email'] 


class CustomUserSettingsForm(forms.ModelForm): 
    class Meta: 
     model = CustomUser 
     fields = ['street', 'post_name', 'post_number'] 

frontend_customuser: 
    id 
    street 
    user_id # not sure how this is created, concat of CustomUser and User fields? 
    post_name 
    post_number 

私はそうのようなUserからのデータを変更するユーザとCustomUserを可能にする形態を有します下記のようにDBに表示/書き込みしようとしています。 Userテーブルを表示して変更することはできますが、CustomUserで管理されている(まだ空のままです)テーブルには触れません(エラーはNOT NULL constraint failed: frontend_customuser.user_idです)。私が間違っているかもしれないことについてのヒント?このデータをすべてCustomUser(これはUser)に書き込むより簡単な方法はありますか?

def settings(request): 
    # Prepare data to be filled into forms. User should always exist so no try/except call. 
    prefill_user = User.objects.get(pk=request.user.id) 

    # In case CustomUser table is empty, instantiate a CustomUser with request.user.id user_id. 
    try: 
     prefill_customuser = CustomUser.objects.get(pk=request.user.id) 
    except ObjectDoesNotExist: 
     prefill_customuser = CustomUser(user_id=request.user.id) 

    if request.method == "GET": 
     # If CustomUser table is empty, fields will appear empty. If prefill_customuser is successful 
     # at retrieving data, I expect this to be populated by values from the database. 
     settings_form_user = BasicUserSettingsForm(initial={'first_name': prefill_user.first_name, 
                  'last_name': prefill_user.last_name, 
                  'email': prefill_user.email}, 
                instance=prefill_user) 
     settings_form_customuser = CustomUserSettingsForm(initial={'street': prefill_customuser.street, 
                    'post_name': prefill_customuser.post_name, 
                    'post_number': prefill_customuser.post_number}, 
                  instance=prefill_customuser) 

    if request.method == "POST": 
     settings_form_user = BasicUserSettingsForm(request.POST, instance=prefill_user) 
     try: 
      customuser_instance = CustomUser.objects.get(pk=request.user.id) 
      settings_form_customuser = CustomUserSettingsForm(request.POST, instance=customuser_instance) 
     except ObjectDoesNotExist: 
      settings_form_customuser = CustomUserSettingsForm(request.POST) 

     if settings_form_user.is_valid() and settings_form_customuser.is_valid(): 
      settings_form_user.save() 
      settings_form_customuser.save() 
     else: 
      settings_form_user = BasicUserSettingsForm(request.POST) 
      settings_form_customuser = CustomUserSettingsForm(request.POST) 

    return render(request, 'frontend/nastavitve.html', 
        {'settings_form_user': settings_form_user, 'settings_form_customuser': settings_form_customuser}) 

答えて

0

最初に私はUserクラスを拡張することがもっともエレガントな解決策になると思っていましたが、今のところ、ForeignKeyがテーブルUserにリンクされている別のテーブルを選択しました。以下に説明する実装は、フォームに入力された値を受け取り、データベース内のテーブルを記録/更新し、フォームの最新のデータを提供します。

# --models.py 
class UserAddress(models.Model): 
    id = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) 
    street = models.CharField(max_length=80, default="") 
    # post = models.ForeignKey(PostNameNum, on_delete=models.CASCADE) 
    post_name = models.CharField(max_length=80, default=None) 
    post_number = models.IntegerField(default=None) 

# --forms.py 
class BasicUserSettingsForm(forms.ModelForm): 
    class Meta: 
     model = User 
     fields = ['first_name', 'last_name', 'email'] 

class UserAddressSettingsForm(forms.ModelForm): 
    class Meta: 
     model = UserAddress 
     fields = ['street', 'post_name', 'post_number'] 

# --views.py 
def settings(request): 
    # Prepare data to be filled into forms. User should always exist so no try/except call. 
    prefill_user = User.objects.get(pk=request.user.id) 

    # In case CustomUser table is empty, instantiate a CustomUser with request.user.id user_id. 
    try: 
     prefill_customuser = UserAddress.objects.get(pk=request.user.id) 
    except ObjectDoesNotExist: 
     prefill_customuser = UserAddress(id=User(id=request.user.id)) 

    if request.method == "GET": 
     settings_form_user = BasicUserSettingsForm(initial={'first_name': prefill_user.first_name, 
                  'last_name': prefill_user.last_name, 
                  'email': prefill_user.email}, 
                instance=prefill_user) 
     settings_form_customuser = UserAddressSettingsForm(initial={'street': prefill_customuser.street, 
                    'post_name': prefill_customuser.post_name, 
                    'post_number': prefill_customuser.post_number}, 
                  instance=prefill_customuser) 

    if request.method == "POST": 
     settings_form_user = BasicUserSettingsForm(request.POST, instance=prefill_user) 
     try: 
      settings_form_customuser = UserAddressSettingsForm(request.POST, instance=prefill_customuser) 
     except ObjectDoesNotExist: 
      settings_form_customuser = UserAddressSettingsForm(request.POST) 

     # if settings_form_user.is_valid() and settings_form_customuser.is_valid(): 
     if settings_form_customuser.is_valid(): 
      settings_form_user.save() 
      settings_form_customuser.save() 
     else: 
      settings_form_user = BasicUserSettingsForm(request.POST) 
      settings_form_customuser = UserAddressSettingsForm(request.POST) 

    return render(request, 'frontend/nastavitve.html', 
        {'settings_form_user': settings_form_user, 
        'settings_form_customuser': settings_form_customuser} 
       ) 
0

これは、基本的なDjangoのUserモデルにOneToOneフィールドとカスタムユーザーを作成する古い方法です。あなたのケースでは、AbstractUserを拡張する必要があり、それはDjangoの1.8以降で使用可能です:

class CustomUser(AbstractUser): 
    street = models.CharField(max_length=80, default="") 
    post_name = models.CharField(max_length=80, default=None) 

settings.pyで新しいユーザーを置く:あなたはベースのユーザ・モデルのaditionalフィールドを追加したい場合は
AUTH_USER_MODEL = <app_name>.CustomUser
このアプローチは動作します。あなたがそれをもっと複雑にする必要があるなら、あなたは退出する必要があります。AbstractBaseUser

+0

Googleで認証しようとするとエラーが発生しました。「パスワード」フィールドはありません。私は何かを上書きしましたか、これは期待されていますか?残念ながら、私はドキュメントの中でこれを見ていません。 「ユーザー」を新たに導入することは安全ですか? –

関連する問題