2016-07-02 2 views
0

djangoユーザーをOneToOneFieldに拡張して、アドレスなどを格納できるようにしました。ModelFormsのOneToOneFieldフィールドを取得する

SiteUserはを使用してUserを拡張するモデルです。 ModelFormUserSiteUserの両方のフィールドを取得するにはどうすればよいですか?

def edit_profile(request): 
    username = request.user 
    user = User.objects.get(username__exact=username) 
    profileform_class = ProfileForm 

    if request.method == 'POST': 
     profileform = profileform_class(data=request.POST, instance=user) 
     if profileform.is_valid(): 
      profileform.save() 
      return redirect('profile') 
    else: 
     profileform = profileform_class(instance=user) 

    return render(request, 'edit_profile.html', { 
     'user': user, 
     'profileform': profileform, 
    }) 

そして、二つのモデル::

class Product(models.Model): 
    order = models.IntegerField(default=0) 
    name = models.CharField(max_length=255) 
    description = models.TextField() 
    image = models.ImageField(upload_to='product-images', default='default.jpg') 
    price = models.FloatField() 
    slug = models.SlugField(unique=True) 


class SiteUser(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    address = models.CharField(max_length=255) 
    post_number = models.CharField(max_length=255, default='') 
    post_location = models.CharField(max_length=255, default='') 

HTMLページは、私が上のフォームをしたい問題の

class ProfileForm(ModelForm): 
    class Meta: 
     model = User 
     fields = ('username', 'first_name', 'last_name', 'email') 


class AddressForm(ModelForm): 
    pass 

ビュー:ここ

は、これまでのところ、関連するコードです。

{% extends 'base.html' %} 
{% block title %} 
    Rediger {{ product.name }} - {{ block.super }} 
{% endblock title %} 

{% block content %} 
    <h1>Rediger "{{ user }}"</h1> 
    <form role="form" action="" method="post"> 
    {% csrf_token %} 
    {{ profileform.as_p }} 
    {{ addressform.as_p }} 
    <button type="submit">Submit</button> 
    </form> 
{% endblock content %} 

答えて

2
  • 1つのオプションはinline formsetsです。これを使用すると、2番目のModelFormは必要ありません。

    インラインフォームセットは、モデルの書式セットの上にある小さな抽象レイヤーです。これらは、外部キーを介して関連オブジェクトを操作する場合を単純化します。

    good examples hereがあります。あなたはインラインフォームセットを回避し、あなたのテンプレートで行ったように、単一の<form>タグの下ProfileFormAddressFormの両方を使用したい場合は

  • あるいは、あなたはthisのようにそれを行うことができます。

    フォーム:

    class ProfileForm(ModelForm): 
        class Meta: 
         model = User 
         fields = ('username', 'first_name', 'last_name', 'email') 
    
    class AddressForm(ModelForm): 
        class Meta: 
         model = SiteUser 
         exclude = ['user'] 
    

    再生回数:

    def edit_profile(request): 
        username = request.user 
        user = User.objects.get(username__exact=username) 
        profileform_class = ProfileForm 
        addressform_class = AddressForm 
    
        if request.method == 'POST': 
         profileform = profileform_class(data=request.POST, instance=user) 
         addressform = addressform_class(data=request.POST, instance=user.siteuser) 
         if all((profileform.is_valid(), addressform.is_valid())): 
          user = profileform.save() 
          address = addressform.save(commit=False) 
          address.user = user 
          address.save() 
          return redirect('profile') 
        else: 
         profileform = profileform_class(instance=user) 
         addressform = addressform_class(instance=user.siteuser) 
    
        return render(request, 'edit_profile.html', { 
         'user': user, 
         'profileform': profileform, 
         'addressform': addressform, 
        }) 
    
+0

だから、これは近い私が欲しかったものに私を得た、ありがとう! しかし、今問題は、アドレスフォームがどのユーザーを参照しているのかわからないことです。したがって、フォームには既にアドレスがある場合は自動入力されず、新しいアドレスを保存することはできません。 フォームの「ユーザー」モデル。pyはすでに1人のユーザーしかいないため、どちらが原因であるかを既に知っています。しかし、単に "SiteUser"を参照しても、現在のユーザーを指し示すことはありません。 スクリプトの他の部分では、モデルを表示したい場合は、モデルのさまざまな部分にアクセスするためにuser.siteuserを使用します。 "all()"は明らかに1つのステートメントだけをとります –

+0

@AndreasHalvorsenTollånes対応するSiteUserモデルを参照するために私の答えを編集しました。 all()への呼び出しを修正しました:リスト/タプルを渡すことになっています。これが動作するかどうか教えてください:) –

+1

はい!これで動作しますが、instance = user.siteuserをelseに追加したいフィールドを自動入力するには:addressform = addressform_class(instance = user.siteuser)^^ –

0

私は、フォームについてあまり知らないが、私はAddressFormをインスタンス化する際に、ここで例示したようにあなたは、「初期」パラメータを使うべきだと思う:https://docs.djangoproject.com/es/1.9/topics/forms/modelforms/#providing-initial-values

ですから、モデルとしてSiteUserであなたのAddressFormクラスを作成し、ときあなたはこのようにそれを作る、ビューでそれをインスタンス化します。

AddressForm(initial={'user': request.user}) 

「ユーザ名が」Userモデルの主キーではない場合、あなたはこのような主キーを取得することができます:

User.objects.get(username=request.user).pk 

を入力し、それを「初期」パラメータで指定します。

関連する問題