列“ user_id”中的空值违反了非空约束Django形式

时间:2019-01-16 03:01:20

标签: python django forms

尝试为用户个人资料页面实现文件上传。我收到以下错误:

  

列“ user_id”中的空值违反了非空约束   详细信息:失败行包含(35,   个人资料/ {now:%Y /%m / YmdHMSext_xg2iZ6M,null,null)。

我已经阅读到它可能与User_ID有关,我尝试传递form.user = request.user,但这没有用。还有两个空值,而不仅仅是一个。

Models.py

class User(AbstractUser):
    # First Name and Last Name do not cover name patterns
    # around the globe.
    name = models.CharField(_('Name of User'), blank=True, 
    max_length=255)
    #accepted_terms_of_service = models.Booleanfield()

    def __str__(self):
        return self.username

    def get_absolute_url(self):
        return reverse('users:detail', kwargs={'username': 
self.username})

# Profile Image
def upload_to(instance, filename):
    now = timezone_now()
    base, ext = os.path.splitext(filename)
    ext = ext.lower()
    return "profile/{now:%Y/%m/%Y%m%d%H%M%S}{ext}"

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, 
on_delete='CASCADE', related_name='user_profile')
    school = models.CharField(max_length=30, null=True, blank=True)
    image = models.ImageField(_("Picture"), upload_to=upload_to, 
null=True, blank=True)

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

views.py

@login_required
def add_image(request):
     form = ProfileImageForm()
     #form.user = request.user
     if request.method == "POST":
         form = ProfileImageForm(data=request.POST, files=request.FILES)
     if form.is_valid():
         form.save()
         return redirect('userPage')
     else:
         return render(request, "users/user_image_form.html", {"form": form
        })

forms.py

class ProfileImageForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ["image"]

2 个答案:

答案 0 :(得分:1)

这是因为在您的Profile模型中,您将user列添加为对NOT NULL强制执行的ForeignKey,因此引发了错误。 为了解决这个问题,您需要修改add_image这样的方法

@login_required
def add_image(request):
     form = ProfileImageForm()
     #form.user = request.user
     if request.method == "POST":
         form = ProfileImageForm(data=request.POST, files=request.FILES)
     if form.is_valid():
         form = form.save(commit=False) # change is here
         form.user=request.user.pk # change is here
         form.save()
         return redirect('userPage')
     else:
         return render(request, "users/user_image_form.html", {"form": form

如果登录,将获得request.user.pk值。但是,如果登录,则需要确认form.user = your_specified_id表中存在ID的User。 如果是这种情况,您是管理员,则需要向其他用户添加图像,以便您需要在add_image方法中传递用户ID。

添加ProfileImageForm.py 在字段列表中添加user

答案 1 :(得分:1)

我认为没有必要同时拥有Profile Model和Custom User Model。因为在您已经自定义User模型时,为什么不将Profile模型的字段也放入User模型。您可以这样处理:

# model

def upload_to(instance, filename):
    now = timezone_now()
    base, ext = os.path.splitext(filename)
    ext = ext.lower()
    return "profile/{now:%Y/%m/%Y%m%d%H%M%S}{ext}"


class User(AbstractUser):
    name = models.CharField(_('Name of User'), blank=True, 
    max_length=255)
    school = models.CharField(max_length=30, null=True, blank=True)
    image = models.ImageField(_("Picture"), upload_to=upload_to, 
                              null=True, blank=True)

    def __str__(self):
        return self.username

    def get_absolute_url(self):
        return reverse('users:detail', kwargs={'username': 
self.username})

# views

@login_required
def add_image(request):
     form = ProfileImageForm(data=request.POST or None, file=request.FILES or None, instance=request.user)
     if request.method == "POST":

        if form.is_valid():
             form.save()
             return redirect('userPage')

     return render(request, "users/user_image_form.html", {"form": form
        })

# forms.py

class ProfileImageForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ["image"]

更新

您可以创建一个post_save信号,该信号将在创建每个用户后创建一个配置文件实例。

def create_user_profile(sender, instance, created, **kwargs):

    if created:
        profile = Profile(user=instance)
        profile.save()

post_save.connect(create_user_profile,
                  sender=User,
                  dispatch_uid="profilecreation-signal")

现在,在您的表单中,您可以直接传递此Profile实例:

@login_required
def add_image(request):
     form = ProfileImageForm(data=request.POST, files=request.FILES, instance=request.user.profile)

     if request.method == "POST":
         if form.is_valid():
             form.save()
             return redirect('userPage')
     else:
         return render(request, "users/user_image_form.html", {"form": form
        })

对于现有用户,您可以从shell创建配置文件:

for user in User.objects.all():
    Profile.objects.get_or_create(user=user)