为什么 Django 在提交表单时在列 "user_id" 中引发 IntegrityError :null 值违反了非空约束?



>我有一个UserSession模型,该模型创建一个使用IP地址和城市数据的会话,以使用Geip2填充模型。我设置了一个表单,该表单采用我希望用户输入但得到的信息:

**django.db.utils.IntegrityError: null value in column "user_id" violates not-null constraint**

当我提交表格时。对象已创建,但表单采用的信息不会保存到对象中。

视图:

class NewLocationCreateForm(CreateView):
        model = UserSession
        success_url = reverse_lazy('post:index')
        form_class = NewLocationCreateForm

 def form_valid(self, form):
        if form.is_valid():
            roote = Post.objects.filter(owner =self.request.user)
            instance = form.save(commit=False)
            instance.owner = self.request.user
            user_logged_in.send(self.request.user, request=self.request)
        return super(NewLocationCreateForm, self).form_valid(form)

    def get_form_kwargs(self):
        kwargs = super(NewLocationCreateForm, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

问题似乎在于:

if form.is_valid():
 return super(NewLocationCreateForm, self).form_valid(form) 

Geoip2的用户会话调用似乎有效,但无法保存表单

forms.py

from .models import  UserSession
from post.models import  Post
from django import forms

class NewLocationCreateForm(forms.ModelForm):
    class Meta:
        model = UserSession
        fields = [
            'g_post',
            'coordinate',
            'place_name'
        ]
    def __init__(self,user=None, *args, **kwargs):
        super(NewLocationCreateForm, self).__init__(*args, **kwargs)
        self.fields['g_post'].queryset = Post.objects.filter(owner=user)

models.py:

from django.conf import settings
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
from django.db.models.signals import pre_save
from analytics.signals import user_logged_in
from analytics.utils import get_client_city_data, get_client_ip
from post.models import Post
User = settings.AUTH_USER_MODEL

class UserSessionManager(models.Manager):
    def create_new(self, user, session_key=None, ip_address=None, city_data=None):
        session_new = self.model()
        session_new.user = user
        session_new.session_key = session_key
        if ip_address is not None:
            session_new.ip_address = ip_address
            if city_data:
                session_new.city_data = city_data
                try:
                    city = city_data['city']
                except:
                    city = None
                session_new.city = city
                try:
                    country = city_data['country_name']
                except:
                    country = None
            session_new.country = country
            session_new.save()
            return session_new
        return None
class UserSession(models.Model):
    g_post            = models.ForeignKey(Post, on_delete=models.CASCADE, null=True)
    user            = models.ForeignKey(User)
    coordinate      = models.CharField(max_length=1000, blank=True)
    place_name      = models.CharField(max_length=250, blank=True)
    location_photo  = models.ImageField(upload_to='location_image', blank=True)
    updated         = models.DateTimeField(auto_now=True, null=True)
    session_key     = models.CharField(max_length=60, null=True, blank=True)
    ip_address      = models.GenericIPAddressField(null=True, blank=True)
    city_data       = models.TextField(null=True, blank=True)
    city            = models.CharField(max_length=120, null=True, blank=True)
    country         = models.CharField(max_length=120, null=True, blank=True)
    active          = models.BooleanField(default=True)
    timestamp       = models.DateTimeField(auto_now_add=True)
    objects = UserSessionManager()
    def __str__(self):
        city = self.city
        country = self.country
        place_name = self.place_name
        if city and country:
            return f"{city}, {country}"
        elif city and not country:
            return f"{city}"
        elif country and not city:
            return f"{country}"
        return self.place_name    
def user_logged_in_receiver(sender, request, *args, **kwargs):
    user = sender
    ip_address = get_client_ip(request)
    city_data = get_client_city_data(ip_address)
    request.session['CITY'] = str(city_data.get('city', 'New York'))
    session_key = request.session.session_key
    UserSession.objects.create_new(
                user=user,
                session_key=session_key,
                ip_address=ip_address,
                city_data=city_data
                )

user_logged_in.connect(user_logged_in_receiver)
在修复

IntegrityError 的 @solarissmoke 修复(将instance.owner更改为 instance.user (旁边,您在此处的 is_valid() 方法中触发user_logged_in()信号:

def form_valid(self, form):
    if form.is_valid():
        roote = Post.objects.filter(owner =self.request.user)
        instance = form.save(commit=False)
        instance.user = self.request.user
        # Here you trigger signal that creates UserSession!
        user_logged_in.send(self.request.user, request=self.request)
    return super(NewLocationCreateForm, self).form_valid(form)

因此,一个对象是用 CreateView 创建的,另一个是用这个信号创建的。删除 form_valid() 中的此行。

编辑:要包含来自信号的数据,只需将其添加到form_valid()中,如下所示:

def form_valid(self, form):
    if form.is_valid():
        roote = Post.objects.filter(owner =self.request.user)
        instance = form.save(commit=False)
        instance.user = self.request.user
        instance.ip_address = get_client_ip(self.request)
        instance.city_data = get_client_city_data(instance.ip_address)
        instance.session_key = self.request.session.session_key
    return super(NewLocationCreateForm, self).form_valid(form)

您的UserSession模型没有定义owner字段,因此在实例上设置该字段对您没有好处。您可能希望改为执行以下操作:

if form.is_valid():
    roote = Post.objects.filter(owner =self.request.user)
    instance = form.save(commit=False)
    instance.user = self.request.user   # You need to set instance.user, not instance.owner
    user_logged_in.send(self.request.user, request=self.request)
    return super(NewLocationCreateForm, self).form_valid(form)

相关内容

  • 没有找到相关文章

最新更新