我有一个UserProfile模型,它与Django用户模型有一对一的关系。
我想通过视图AddStory
将数据插入到UserProfile模型中,但我得到IntegrityError at /AddStory/ NOT NULL constraint failed: portal_userprofile.user_id
更具体地说,我想通过主页上给出的表单将一些文本添加到UserProfile模型的ShoppingHistory属性中。我有另一个页面,其中列出了ShoppingHistory.html
上此属性的值(如果用户提供)。
所有用户都是唯一的,一旦该用户登录,我如何确保为特定用户添加此属性?如何在用户登录后引用该用户?
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserProfile(AbstractUser):
profile_pic = models.ImageField(upload_to='profile_images', blank=True)
StaffMember = models.BooleanField(default=False)
ShoppingHistory = models.TextField()
ShoppingWishList = models.TextField()
def __unicode__(self):
return self.user.username
views.py:
from django.shortcuts import render
from django import forms
from portal import models
from portal.forms import UserProfileForm
from django.contrib.auth import authenticate, login
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
# Create your views here.
def register(request):
regStatus = False
if request.method == 'POST':
#grab info from raw information
profile_form=UserProfileForm(data=request.POST)
if profile_form.is_valid():
user=profile_form.save(commit=False)
#hash the password for security using the djangohash default method
user.set_password(user.password)
if 'profile_pic' in request.FILES:
profile_pic = request.FILES['profile_pic']
user.save()
regStatus = True
else:
print profile_form.errors
else:
profile_form = UserProfileForm()
return render(request, 'register.html', {'profile_form': profile_form, 'registered': regStatus})
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
login(request, user)
return HttpResponseRedirect('/home/')
else:
return HttpResponse('Invalid login credentials')
else:
return render(request, 'login.html', {})
@login_required
def homepage(request):
return render(request, 'home.html', {})
def AddStory(request):
if request.method == 'POST':
story = request.POST.get('ShoppingHistory')
username = request.POST.get('username')
p=models.UserProfile(ShoppingHistory=story, username=username)
p.save()
return render(request, 'ShoppingHistory.html', {'story': p})
return render(request, 'ShoppingHistory.html', {})
Home.html中:
{% if user.is_authenticated %}
<p> WELCOME, thanks for logging in {{user.username}} </p>
<form id="user_form" method="post" action="/AddStory/" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="ShoppingHistory" value="" />
<input name="username" value="{{user.username}}" DISABLED />
<input type="submit" name="submit" value="Add Story" />
{% endif %}
ShoppingHistory.html:
{% if user.is_authenticated %}
{% csrf_token %}
<p> WELCOME, thanks for logging in {{user.username}} </p>
<p> Your Shopping Stories: </p>
<p>{{user.ShoppingHistory}}</p>
{% endif %}
forms.py
from django import forms
from portal.models import UserProfile
class UserProfileForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = UserProfile
fields = ('username', 'first_name', 'last_name', 'email', 'password', 'profile_pic')
答案 0 :(得分:1)
使用AbstractUser创建自定义用户要好得多:
from django.contrib.auth.models import AbstractUser
class UserProfile(AbstractUser):
pass
您的问题是,当您创建UserProfle实例时,您必须将User设置为它,但实际上您想要创建它,因此您需要先创建用户,然后您必须在DB中使用用户表。为了什么?
有关自定义用户的更多信息:docs
<强>更新强>
错误在此行p=models.UserProfile(ShoppingHistory='story',)
中。您的UserProfile模型要求用户创建UserProfile,而您不需要设置用户实例。但我想说你有一个错误的方法来创建自定义用户。这个想法是你的数据库中有两个用户表。一个用户,另一个用于UserProfile。它们通过OneToOne关系连接,但它不是继承。每当您想要创建UserProfile实例时,您都需要为其创建一个User实例。这就是为什么我肯定会建议您使用AbstractUser创建自定义用户模型的原因。然后,您不需要考虑在创建用户时指定用户。
更新2
如果您想为他创建故事,则无需创建新用户。你可以:
def AddStory(request):
if request.method == 'POST':
story = request.POST.get('ShoppingHistory')
request.user.ShoppingStory = story
request.user.save()
return render(request, 'ShoppingHistory.html', {'story': story})
return render(request, 'ShoppingHistory.html', {})