Модель UserProfile не сохраняет ForeignKeys - PullRequest
0 голосов
/ 08 марта 2012

Я следовал следующему руководству: http://www.turnkeylinux.org/blog/django-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)

Модель UserProfile

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 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>

>>> pcbuild.owner
    <User: Trevor>

>>> user.profile.email_hash
    u'd41d8cd98f00b204e9800998ecf8427e'

>>> user.profile.current_build = pcbuild
>>> user.profile.save()
>>> user.profile.current_build
    # nothing is stored/outputted - this is the problem!

Я новичок в Django, и, хотя Google до сих пор помогал, этот я не победил после нескольких часов.Если вам потребуется дополнительная информация по этому вопросу, я буду рад ее предоставить!

Спасибо.

РЕДАКТИРОВАТЬ:

Вещи, которые я нашел, которые могут быть полезны (но не решили мою конкретную проблему):

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Вы будете сталкиваться с загадочными ошибками по линии, используя свойство.Поскольку отношение UserProfile к User является OneToOneField, вы можете получить доступ к экземпляру профиля из экземпляра, выполнив user.userprofile.Если вы хотите изменить имя, вы можете обновить свойство OneToOneField related_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)
0 голосов
/ 08 марта 2012

Я понял это - но я открыт для других ответов и проверю позже. Я почти уверен, что это как-то связано с лямбда-функцией, которую я использую для получения профиля. Как я это сделал в оболочке python:

>>> 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!

В основном мне пришлось присвоить user.profile его собственной переменной ( профиль в примере), а затем после изменения переменной сохранить ее вместо объекта пользователя.

Кажется, немного неловко, но это работает.

...