Why does Django raised IntegrityError :null value in column "user_id" violates not-null constraint when a form is committed?
Why does Django raised IntegrityError :null value in column "user_id" violates not-null constraint when a form is committed?
我有一个 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)
您的 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)
在修复 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 模型,它创建一个会话,该会话使用 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)
您的 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)
在修复 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)