Django 用户配置文件模型isn';不要保存外国钥匙

Django 用户配置文件模型isn';不要保存外国钥匙,django,django-models,foreign-keys,save,user-profile,Django,Django Models,Foreign Keys,Save,User Profile,我遵循了以下指南:它运行得很好,只是我似乎无法将ForeignKey保存到用户配置文件中 模型 PCBuild模型 from django.contrib.auth.models import User from django.db import models class PCBuild(models.Model): name = models.CharField(max_length=50) owner = models.ForeignKey(User) import d

我遵循了以下指南:它运行得很好,只是我似乎无法将ForeignKey保存到用户配置文件中


模型

PCBuild模型

from django.contrib.auth.models import User
from django.db import models

class PCBuild(models.Model):
    name = models.CharField(max_length=50)
    owner = models.ForeignKey(User)
import datetime
import md5

from apps.pcbuilder.models import PCBuild
from django.contrib.auth.models import User
from django.db import models

class UserProfile(models.Model):   
    user = models.OneToOneField(User)
    email_hash = models.CharField(max_length=200) #MD5 hash of e-mail

    current_build = models.ForeignKey(PCBuild, 
        related_name='current_build', null=True, blank=True)

    def __unicode__(self):
        return self.user.email 


User.profile = property(lambda u: UserProfile.objects.get_or_create(
                            user=u, 
                            email_hash=md5.new(u.email).hexdigest())[0])
用户配置文件模型

from django.contrib.auth.models import User
from django.db import models

class PCBuild(models.Model):
    name = models.CharField(max_length=50)
    owner = models.ForeignKey(User)
import datetime
import md5

from apps.pcbuilder.models import PCBuild
from django.contrib.auth.models import User
from django.db import models

class UserProfile(models.Model):   
    user = models.OneToOneField(User)
    email_hash = models.CharField(max_length=200) #MD5 hash of e-mail

    current_build = models.ForeignKey(PCBuild, 
        related_name='current_build', null=True, blank=True)

    def __unicode__(self):
        return self.user.email 


User.profile = property(lambda u: UserProfile.objects.get_or_create(
                            user=u, 
                            email_hash=md5.new(u.email).hexdigest())[0])

问题实例

>>来自django.contrib.auth.models导入用户
>>>从apps.pcbuilder.models导入PCBuild
>>>从django.shortcuts导入获取对象或404
>>>用户=获取对象或404(用户,主键=2)
>>>使用者
>>>pcbuild=获取对象或404(pcbuild,pk=11)
>>>印刷电路板
>>>pcbuild.owner
>>>user.profile.email\u散列
u'd41d8cd98f00b204e9800998ecf8427e'
>>>user.profile.current_build=pcbuild
>>>user.profile.save()文件
>>>user.profile.current_构建
#没有存储/输出任何内容-这就是问题所在!

我是Django的新手,虽然谷歌到目前为止对我很有帮助,但几个小时后我还没有征服它。如果需要更多关于这个问题的信息,我很乐意提供

谢谢


编辑:

我发现可能有用的东西(但没有解决我的特殊问题):


我找到了答案-但我仍然愿意接受其他答案&稍后再查看。我很确定这与我用来获取配置文件的lambda函数有关。我是如何在python shell中实现的:

>>> from django.contrib.auth.models import User
>>> from apps.pcbuilder.models import PCBuild
>>> from django.shortcuts import get_object_or_404
>>> user = get_object_or_404(User, pk=2)
>>> user
    <User: Trevor>

>>> pcbuild = get_object_or_404(PCBuild, pk=11)
>>> pcbuild
    <PCBuild: StackOverflowBuild>

>>> user.profile.current_build
    # nothing (which is expected as there is nothing 
    # yet in the current_build of this user profile)


# NOTE: I'm creating a new "profile" variable that holds the user profile.

>>> profile = user.profile
>>> profile
    <UserProfile: Trevor>

>>> profile.current_build
    # nothing (which is expected as there is nothing 
    # yet in the current_build of this user profile)

>>> profile.current_build = pcbuild
>>> profile.save()

>>> user.profile.current_build
    <PCBuild: StackOverflowBuild>

    # As you can see, it worked!
>>来自django.contrib.auth.models导入用户
>>>从apps.pcbuilder.models导入PCBuild
>>>从django.shortcuts导入获取对象或404
>>>用户=获取对象或404(用户,主键=2)
>>>使用者
>>>pcbuild=获取对象或404(pcbuild,pk=11)
>>>印刷电路板
>>>user.profile.current_构建
#没有(这是预期的,因为没有
#但在当前的用户配置文件中)
#注意:我正在创建一个保存用户配置文件的新“profile”变量。
>>>profile=user.profile
>>>侧面图
>>>profile.current_build
#没有(这是预期的,因为没有
#但在当前的用户配置文件中)
>>>profile.current_build=pcbuild
>>>profile.save()
>>>user.profile.current_构建
#正如你所看到的,它成功了!
基本上,我必须将user.profile分配给它自己的变量(示例中的profile),然后在修改变量后,保存该变量,而不是用户对象


这似乎有点尴尬,但它是有效的。

使用该属性之后,您将遇到不确定的bug。由于
UserProfile
User
的关系是一个
OneToOneField
,因此您可以通过执行
User.UserProfile
从实例访问配置文件实例。如果要更改名称,可以更新
OneToOneField
相关\u name
属性

创建用户时,使用信号自动创建配置文件,如下所示:

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

def create_profile(sender, **kwargs):
    """Create a UserProfile instance when a User is created."""
    u = kwargs['instance']
    if kwargs['created']:
        UserProfile.objects.get_or_create(
                        user=u, 
                        email_hash=md5.new(u.email).hexdigest())

post_save.connect(create_profile, sender=User)

这将是非常混乱/容易出现错误的。只需删除属性并使用
user.get_profile()
@sdolan我想我的问题是,如果用户还没有UserProfile(lambda函数的用途),该怎么办?我将看看使用
user.get\u profile()
是否可以为已经有配置文件的用户提供此技巧。谢谢。是的,效果好多了。请随便把它作为答案贴出来,我会接受的。我知道lambda函数有点可疑。在创建
用户
实例时使用信号创建一个。我添加了一个关于如何执行的答案。啊,谢谢。我已经将所有内容从
user.profile
更改为
user.get\u profile()
,但如果以后要更改名称,我会记下。