如何链接这两个模型,以便更新同一个实例?

时间:2015-10-28 02:38:43

标签: django models relationships

我真的想用Django构建这个应用程序,让人们注册并创建可以编辑的用户实例。每个用户实例已经与OneToOne链接到UserProfile,因为我不想弄乱原始用户模型。如果该用户已登录,则UserProfile将具有他/她可以注册游戏的字段。

即。比利想要报名参加星期一Smash Melee。他登录,单击表单上的选项,链接到User,Billy的UserProfile将更新已注册的游戏选项和用户标签到用户配置文件。

用户个人资料链接到用户的部分工作正常,但我不知道如何使用新的锦标赛注册表单更新UserProfile,以便它可以更改链接到的UserProfile字段登录的用户。

Django模特:

class UserProfile(models.Model):
#User profile for registered users. SEPARATE USERBASE TO PLAYER_RANKING
#To Do: add more customizeability and more access for registered.
#weekly e-mails, ability to register for weeklies...
user = models.OneToOneField(User)
picture = models.ImageField(upload_to='profile_images', blank=True)


MON = 'ME'
TUE = 'S4'
THR = 'PM'
reg_game_choices = (
    (MON, "Melee"),
    (TUE, "Smash 4"),
    (THR, "PM"),
    )
reg_game_choice = models.CharField(max_length=2,
                                   choices=reg_game_choices,
                                   default="")
user_tag = models.CharField(max_length=60, default = "")

def __str__(self):
    return self.user.username

形式:

class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())

class Meta:
    model = User
    fields = ('username', 'password')

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

class TournyRegForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('reg_game_choice', 'user_tag',)

查看:

@login_required
def tourny_reg(request):
    #Registering for tournaments
    context_dict = {}

    weekday = datetime.datetime.today().weekday()
    day_names = ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']
    game_days = ['SMASH MELEE', 'SMASH 4', 'CLOSED', 'PROJECT M &     FIGHTING GAMES',
            'FRIENDLIES', 'CLOSED', 'CLOSED']
    day_title = day_names[weekday]
    game_day = game_days[weekday]


    context_dict['day'] = day_title
    context_dict['game_of_the_day'] = game_day

    if request.method == 'POST':
        tourny_form = TournyRegForm(data=request.POST)
        if tourny_form.is_valid():
            tourny_form.save()
        else:
            print (tourny_form.errors)
    else:
        tourny_form = TournyRegForm()

    context_dict['tourny_form'] = tourny_form



return render(request, 'Kappa/tourny_reg.html', context_dict)

它在html和本地服务器上显示完全正常,但是当我尝试时,它给了我一个完整性错误。

/ Kappa / tourny_reg /

中的IntegrityError

NOT NULL约束失败:Kappa_userprofile.user_id 例外值:

NOT NULL约束失败:Kappa_userprofile.user_id  ▶本地变种 在tourny_reg中的C:\ Users \ Kyle \ Documents \ GitHub \ Kappa_Ranks \ Kappa \ views.py

1 个答案:

答案 0 :(得分:1)

基本上,您想知道如何保存与登录用户相关的事物的实例。这很容易。

解释为什么会出现NOT NULL错误:您的TournyRegForm类未被告知显示“用户”的输入字段,因此它不是。因此,当您去保存表单时,将为用户字段填写“无”。数据库正在抱怨,因为“非空”'字段有一个NULL值,这是一个问题..所以这个错误是合法的。

但是这个字段不在表单上是好的..因为你不希望用户通过表单告诉我们他们是谁,你想获得关于他们是谁的信息他们登录的事实.Django auth模块将此信息放在Request对象中,您可以轻松地获取它。您需要做的就是在保存模型之前填写正确的用户,如下所示:

if tourny_form.is_valid():
    # commit= False tells the modelform to just create the model instance
    # but don't save it yet.
    user_profile = tourny_form.save(commit=False)
    # associate this user_profile with the logged in user.. it is always
    # present in the request object if you are using django's         auth module.
    user_profile.user = request.user
    # now save it
    user_profile.save()

因此,它负责保存与当前登录用户相关的模型。但是你有其他问题。例如,您是否希望每次都保存一个新的UserProfile?我不认为你这样做..所以在你的GET上你需要做这样的事情:

user_profile = UserProfile.objects.filter(user=request.user).first()
tourny_form = TournyRegForm(instance=user_profile)

这将从数据库中获取当前登录的用户的UserProfile,然后使用该实例初始化表单,因此当用户返回时,他们将能够编辑他们的个人资料。

现在,如果你真的希望用户能够注册多个游戏..你需要一个游戏模型来存储游戏信息,与你的UserProfile有一对多的关系。这可以通过在Game模型中使用ForeignKey字段来将其与UserProfile相关联。因此每个用户只有一个UserProfile但可以有多个游戏。