Python 将用户配置文件与django中的其他类链接(在postgresql数据库中)

Python 将用户配置文件与django中的其他类链接(在postgresql数据库中),python,django,postgresql,Python,Django,Postgresql,我是django的新手,我正在尝试让两个类在数据库中协同工作。更准确地说,我希望用户能够创建设备,然后在数据库中链接用户和设备(我使用的是postgresql数据库) models.py class Device(models.Model): deviceNb = models.CharField(max_length = 50, null=True) temperature = models.IntegerField() battery = models.Integer

我是django的新手,我正在尝试让两个类在数据库中协同工作。更准确地说,我希望用户能够创建设备,然后在数据库中链接用户和设备(我使用的是postgresql数据库)

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

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\u userprofile(包含以下表格列):

userprofile_设备(包含以下表列):


问题是,我希望能够有一个设备Id与用户已经创建的内容相关联,这样用户和设备都可以链接

当您在模型表单中调用“保存”时,模型将保存在数据库中并返回。 但在代码中,您创建了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
        ...

在modelform中调用“save”时,模型将保存在数据库中并返回。 但在代码中,您创建了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
        ...

我用的是wilkus的解决方案,但有一个小小的转折

添加了以下行

if form.is_valid():
      prof = form.save(commit=False)
      prof.device_id = device
      prof.save()
这允许您从form.save(commit=false)返回一个对象,而不将其发送到数据库,然后我使用该实例更改设备_id(显然不在表单字段中),然后保存它(从而发送到数据库)

因此,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()
            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)

我用的是wilkus的解决方案,但有一个小小的转折

添加了以下行

if form.is_valid():
      prof = form.save(commit=False)
      prof.device_id = device
      prof.save()
这允许您从form.save(commit=false)返回一个对象,而不将其发送到数据库,然后我使用该实例更改设备_id(显然不在表单字段中),然后保存它(从而发送到数据库)

因此,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()
            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)

您的
UserProfile
似乎没有设备。根据上面的models.py关系,您应该可以通过python中的
user\u profile.device.id
访问设备id。您的
UserProfile
似乎没有设备。基于上面的models.py关系,您应该可以通过在python中执行
user\u profile.device.id
来访问设备id。不幸的是,这对我不起作用。设备id仍然不在名为device\u id的my userprofile\u userprofile列中。问题是:request.user.profile.device=设备似乎无法正常工作。因为当我打印device.id(它是正确的id)时,但当我打印request.user.profile.device时,它仍然为非。不幸的是,这对我不起作用。设备id仍然不在名为device\u id的my userprofile\u userprofile列中。问题是:request.user.profile.device=设备似乎无法正常工作。因为当我打印device.id(它是正确的id)时,但当我打印request.user.profile.device时,它仍然是空的