2016-07-12 3 views
0

私はかなり新しいdjangoです。私は2つのクラスをデータベースで一緒に使うようにしています。ユーザプロファイルをdjangoの他のクラスとリンクする(postgresql db内)

models.py

class Device(models.Model): 
    deviceNb = models.CharField(max_length = 50, null=True) 
    temperature = models.IntegerField() 
    battery = models.IntegerField() 

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    profession= models.CharField(max_length=50, null=True) 
    device = models.OneToOneField(Device, null=True) # null = true is to allow null values for devices 

User.profile = property(lambda u : UserProfile.objects.get_or_create(user=u)[0]) 

forms.py

(Iは、PostgreSQLデータベースを使用しています)より正確には、私は、ユーザーがデバイスを作成することができるようにしたいし、データベース内のユーザーとデバイスをリンク
class DeviceForm(forms.ModelForm): 
    class Meta: 
     model = Device 
     fields = ('deviceNb', 'temperature', 'battery',) 


class UserProfileForm(forms.ModelForm): 
    class Meta: 
     model = UserProfile 
     fields = ('profession',) 

views.py

def user_profile(request): 
    user = request.user 
    profile = user.profile 
    device = profile.device 
    if request.method == 'POST': 
     #we want to populate the form with the original instance of the profile model and insert POST info on top of it 
     device_form = DeviceForm(request.POST, instance=device) 

     if device_form.is_valid(): 
      dev = device_form.save() 
      device = dev 
      form = UserProfileForm(request.POST, instance=profile) 

      if form.is_valid(): 
       form.save() 
       #to go back to check that the info has changed 
       return HttpResponseRedirect('/accounts/loggedin') 

    else: 
     form = UserProfileForm(instance=profile) 
     device_form = DeviceForm(instance=device) 

    args = {} 

    args['form'] = form 
    args['device_form'] = device_form 

    return render(request, 'profile.html', args) 

さて、PostgreSQLで、私は次のテーブルを持っている:

userprofile_userprofile(次の表の列が含まれています):

id : OK (filled) 
user_id : OK (filled) 
device_id : PROBLEM : NOT FILLED 
profession : OK (filled) 

userprofile_device(次の表の列が含まれています):

id : OK 
temperature: OK 
battery: OK 
deviceNb : OK 

事は、私が持ってできるようにしたいですユーザとデバイスが両方ともリンクされるように、ユーザが既に作成したものに関連付けられたデバイスID

+0

。上の** models.py **関係に基づいて、あなたはpythonで 'user_profile.device.id'を実行することによってデバイスIDにアクセスする必要があります。 –

答えて

1

モデルフォームで「保存」を呼び出すと、m odelはデータベースに保存され、返されます。 しかし、あなたのコードでは、以前に作成されたデバイスなしでUserProfileFormのインスタンスとインスタンスを作成します。問題

... 
if request.method == 'POST': 
    device_form = DeviceForm(request.POST, instance = device) 

    if device_form.is_valid(): 
     device = device_form.save() 
     request.user.profile.device = device 
     form = UserProfileForm(request.POST, instance=request.user.profile) 
     if form.is_valid(): 
      form.save() 
      return HttpResponseRedirect('/accounts/loggedin') 
     else: 
      device.delete() 
      not_valid_form = True 
    else: 
     not_valid_device_form = True 
    if not_valid_form or not_valid_device_form: # when this is a get request 
     ... 
+0

残念ながら、これは私のためには機能しませんでした。デバイスIDはまだ私のuserprofile_userprofile列のdevice_idにはありません – Rose

+0

問題は次のとおりです。request.user.profile.device = device 実際には動作していないようです。デバイスID(適切なID) を印刷するときですが、私がrequest.user.profile.deviceを印刷するとき、それは何も残っていません – Rose

1

を解決する ここに1つの方法は、私がwilkusソリューションを使用しますが、小さなひねりを加えた、

は、次の行

if form.is_valid(): 
     prof = form.save(commit=False) 
     prof.device_id = device 
     prof.save() 

これはあなたがからオブジェクトを返すことができますを追加しましたform.save(コミット= false)をデータベースに送信せずに、そのインスタンスを使用してdevice_id(フォームフィールドに明示的にない)を変更してから保存してください(したがって、dbに送信)

したがって、views.pyは以下のとおりです。あなたの `UserProfile`がデバイスを持っていないように思え

def user_profile(request): 
    user = request.user 
    profile = user.profile 
    device = profile.device 
    if request.method == 'POST': 
     #we want to populate the form with the original instance of the profile model and insert POST info on top of it 
     device_form = DeviceForm(request.POST, instance=device) 

     if device_form.is_valid(): 
      dev = device_form.save() 
      form = UserProfileForm(request.POST, instance=profile) 

      if form.is_valid(): 
       prof = form.save(commit=False) 
       prof.device_id = dev 
       prof.save() 

       #to go back to check that the info has changed 
       return render_to_response('loggedin.html', {'real_device': dev, 'profile_prof': request.user.profile.profession, 'user_device': request.user.profile.device}) 

    else: # when this is a get request 
      #this is the preferred way to get a users info, it is stored that way 
     #if we have a user that has already selected info, it will pass in this info 
     form = UserProfileForm(instance=profile) 
     device_form = DeviceForm(instance=device) 

    args = {} 

    args['form'] = form 
    args['device_form'] = device_form 

    return render(request, 'profile.html', args) 
関連する問題