Integrity eror not null constraint failed - django

Exception Type: IntegrityError
Exception Value:
NOT NULL constraint failed: Cart.cart_id
#mymodel:
class Cart(models.Model):
cart_id=models.CharField(max_length=250,blank=True)
def _cart_id(request):
cart=request.session.session_key
if not cart:
cart=request.session.create()
def add_cart(request,product_id):
product=Product.objects.get(id=product_id)
try:
cart=Cart.objects.get(cart_id=_cart_id(request))
except Cart.DoesNotExist:
cart=Cart.objects.create(cart_id=_cart_id(request))
cart.save()

Replace your Cart model with cart_id=models.CharField(max_length=250,blank=True, null=True)

Your function _cart_id() return nothing and you are using it for getting or creating cart_id.
class Cart(models.Model):
cart_id=models.CharField(max_length=250,blank=True)
def _cart_id(request):
cart=request.session.session_key
if not cart:
cart=request.session.create()
return cart
def add_cart(request, product_id):
product=Product.objects.get(id=product_id)
try:
cart=Cart.objects.get(cart_id=_cart_id(request))
except Cart.DoesNotExist:
cart=Cart.objects.create(cart_id=_cart_id(request))
cart.save()

Related

how to pass the Integrity error django and DRF without stoping execution raising the error

I am byulding an API using django and DRF my code is this
models.py
class Company(models.Model):
"""Company object."""
name_company = models.CharField(max_length=255)
symbol = models.CharField(max_length=10, unique=True)
cik = models.CharField(max_length=150, blank=True)
sector = models.CharField(max_length=150, blank=True)
industry_category = models.CharField(max_length=150, blank=True)
company_url = models.TextField(blank=True)
description = models.TextField(blank=True)
def __str__(self):
return self.name_company
views.py
class CompanyViewSet(viewsets.ModelViewSet):
"""View for manage company APIs."""
serializer_class = serializers.CompanyDetailSerializer
queryset = Company.objects.all()
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get_serializer_class(self):
"""Return the serializer class for request."""
if self.action == 'list':
return serializers.CompanySerializer
return self.serializer_class
def perform_create(self, serializer):
"""Create a new Company."""
try:
serializer.save()
except IntegrityError:
print('Symbol exists already.')
pass
serializers.py
class CompanySerializer(serializers.ModelSerializer):
"""Serializer for Company."""
class Meta:
model = Company
fields = [
'id', 'name_company', 'symbol', 'cik', 'sector',
'industry_category', 'company_url',
]
read_only_fields = ['id']
def create(self, validated_data):
try:
instance, created = Company.objects.get_or_create(**validated_data)
if created:
return instance
except IntegrityError:
pass
class CompanyDetailSerializer(CompanySerializer):
"""Serializer for Company details."""
class Meta(CompanySerializer.Meta):
fields = CompanySerializer.Meta.fields + ['description']
And right now i am doing unit tests using in this file.
test_company.py
def create_company(**params):
"""Create and return a sample company."""
defaults = {
'name_company': 'Apple',
'symbol': 'AAPL',
'cik': '0000320193',
'sector': 'Technology',
'industry_category': 'Consumer Electronics',
'company_url': 'https://www.apple.com/',
'description':'',
}
defaults.update(params)
company = Company.objects.create(**defaults)
return company
def test_retrieve_companies(self):
"""Test retrieving a list of Companies."""
create_company()
create_company()
create_company(
name_company='Tesla',
symbol='TSLA',
)
res = self.client.get(COMPANIES_URL)
companies = Company.objects.all().order_by('id')
serializer = CompanySerializer(companies, many=True)
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data, serializer.data)
I am getting IntegrityError, what i want is that the run time continue without stopping execution raising the error that is why i am testing it inserting APPLE twice.
I am trying to catch the error with this code in the views.py but does not catch it.
def perform_create(self, serializer):
"""Create a new Company."""
try:
serializer.save()
except IntegrityError:
print('Symbol exists already.')
pass
my error is this:
django.db.utils.IntegrityError: duplicate key value violates unique constraint "core_company_symbol_50a489f1_uniq"
DETAIL: Key (symbol)=(AAPL) already exists.
Thank you in advance.

How to handle IntegrityError unique constraint correctly in Django 3.2

Hello i stacked with that simple thing. I need validation with two fields in model their
combination must be unique. These is work almost as want, but after i try to add a new combination it raise IntegrityError instead validation error in my form. Any workaround to handle it?
#Model(is not all field but it not Necessary in my question):
class AggSubnet(models.Model):
region = models.ForeignKey("db_info.Region", on_delete=models.PROTECT, related_name='get_agg_by_region')
subnet_ip = models.GenericIPAddressField()
class Meta:
constraints = [
models.UniqueConstraint(fields=['subnet_ip','region'], condition=~Q(subnet_ip__startswith='172.'), name='agg_subnet_unique'),
]
def __str__(self):
return f'{self.region} {self.subnet_ip}/{self.subnet_prefix}'
def get_absolute_url(self):
return reverse(f'{self.__class__.__name__}{DETAIL_SUFFIX}', kwargs={"pk": self.pk})
#View:
class AggregateSubnetCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = AggregateSubnet
template_name = 'Subnet_create.html'
fields = ('region', 'subnet_ip')
success_message = "%(subnet_ip)s was created successfully"
def form_valid(self, form):
form.instance.created_by = self.request.user
form.instance.updated_by = self.request.user
return super().form_valid(form)
I mean how i can replace:
enter image description here
to something like this:
enter image description here
#UPDATE(SOLVE):
#That's solve my problem. I've just override clean method:
class AggregateSubnetForm(forms.ModelForm):
class Meta:
model = AggregateSubnet
fields = ('region', 'subnet_ip', 'subnet_prefix',)
def clean(self):
cleaned_data = self.cleaned_data
subnet_ip = cleaned_data['subnet_ip']
if AggregateSubnet.objects.filter(subnet_ip=subnet_ip).exists() and '172.' not in subnet_ip:
raise ValidationError(
('Invalid value: %(value)s this subnet already exist. Only private ip startswith 172. can be duplicated!'),
params={'value': subnet_ip},
)
return super().clean()
Add this line to your model Meta class:
unique_together = (('subnet_ip', 'region'),)
But keep the constraint in place.
You can also add a validation in the form cleaning process:
class AggSubnet(models.Model):
def clean(self):
if self.__class__._default_manager.filter(region=self.region, subnet_ip=self.subnet_ip).exlude(pk=self.pk).exists():
raise forms.ValidationError(...)
I use all three of them simultanously just in case.

Django-import-export update_or_create with UniqueConstraint

I have this Profile model together with a constraint similar to a unique_together:
class Profile(models.Model):
#Personal Information
firstname = models.CharField(max_length=200)
lastname = models.CharField(max_length=200, blank=True, null=True)
email = models.EmailField(max_length=200)
investor_type = models.CharField(max_length=200, choices=investor_type_choices)
class Meta:
constraints = [
models.UniqueConstraint(fields=['email', 'investor_type'], name='email and investor_type')
]
I want to implement a function update_or_create on the Profile which uses the email and investor_type as the argument for searching for the object.
I tried adding this to my ProfileResource:
def before_import_row(self, row, row_number=None, **kwargs):
try:
self.email = row["email"]
except Exception as e:
self.email = None
try:
self.investor_type = row["investor_type"]
except Exception as e:
self.investor_type = None
def after_import_instance(self, instance, new, row_number=None, **kwargs):
try:
# print(self.isEmailValid(self.email), file=sys.stderr)
if self.email and self.investor_type:
profile, created = Profile.objects.update_or_create(
email=self.email,
investor_type=self.investor_type,
defaults={
'firstname': 'helloo',
'lastname': 'wooorld',
})
except Exception as e:
print(e, file=sys.stderr)
but adding a non-existing Profile object:
through django-import-export:
is already giving out an error, Profile with this Email and Investor type already exists despite it not existing in the first place.

Django: Cart matching query does not exist

I've a form that creates a Cart with the text "Random" in a character field, if there is not a Cart object created. This is only to get this recently object's id if it is not already created.
cart = Cart.objects.get(id=cart_id)
I get an error saying that this query generates an error, however I can see the value of cart_id as a cookie so the Query should execute without problem. But it doesn't according to the error message.
Exception Type: DoesNotExist
Exception Value: Cart matching query does not exist.
As you can see in my view, I'm using this:
cart_id = self.request.COOKIES.get('cart_id')
if not cart_id:
cart = Cart.objects.create(cart_id="Random")
cart_id = cart.id
cart = Cart.objects.get(id=cart_id)
To get the cookie cart_id if it does not exist I created a Cart object with the Random text, only to get it's ID.
Why I'm getting the error?
View.py:
class StepOneView(FormView):
form_class = StepOneForm
template_name = 'shop/medidas-cantidades.html'
success_url = 'subir-arte'
def get_initial(self):
# pre-populate form if someone goes back and forth between forms
initial = super(StepOneView, self).get_initial()
initial['size'] = self.request.session.get('size', None)
initial['quantity'] = self.request.session.get('quantity', None)
initial['product'] = Product.objects.get(
category__slug=self.kwargs['c_slug'],
slug=self.kwargs['product_slug']
)
return initial
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['product'] = Product.objects.get(
category__slug=self.kwargs['c_slug'],
slug=self.kwargs['product_slug']
)
return context
def form_invalid(self, form):
print('Step one: form is NOT valid')
def form_valid(self, form):
cart_id = self.request.COOKIES.get('cart_id')
if not cart_id:
cart = Cart.objects.create(cart_id="Random")
cart_id = cart.id
cart = Cart.objects.get(id=cart_id)
item = CartItem.objects.create(
size=form.cleaned_data.get('size'),
quantity=form.cleaned_data.get('quantity'),
product=Product.objects.get(
category__slug=self.kwargs['c_slug'],
slug=self.kwargs['product_slug']
),
cart=cart
)
response = HttpResponseRedirect(self.get_success_url())
response.set_cookie("cart_id", cart_id)
response.set_cookie("item_id", item.id)
return response
models.py:
class Cart(models.Model):
cart_id = models.CharField(max_length=100)
date_added = models.DateField(auto_now_add=True)
class Meta:
db_table = 'Cart'
ordering = ['date_added']
def __str__(self):
return str(self.id)
Try this:
def form_valid(self, form):
cart_id = self.request.COOKIES.get('cart_id')
if cart_id:
try:
cart = Cart.objects.get(id=cart_id)
except ObjectDoesNotExist:
# supplied ID doesn't match a Cart from your BD
cart = Cart.objects.create(cart_id="Random")
else:
cart = Cart.objects.create(cart_id="Random")
No need to create the Cart objects, just to get its ID and they hit the DB again to retrieve the same instance.
The idea is:
Do you have cart_id on session cookies? If so, try to get the Cart object based on it.
If that fails, it means that the supplied cart_id doesn't match an object from your DB
If no cart_id on session cookies, then simply create your new Cart object.

`NOT NULL constraint failed:` when try to Create a User

I encounter error NOT NULL constraint failed: when intend to create a User account:
The model data code:
class ActivateCode(models.Model):
""" """
user = models.ForeignKey(User, on_delete=models.CASCADE)
code = models.CharField(max_length=100)
date_expired = models.DateTimeField(default=tomorrow)
def __str__(self):
return self.code
the register in views.py
def register(request):
if request.method == "GET":
form = UserForm()
if request.method == "POST":
form = UserForm(request.POST)
print(vars(form))
if form.is_valid():
user = User.objects.create_user(
form.cleaned_data['username'],
first_name=form.cleaned_data['first_name'],
last_name=form.cleaned_data['last_name'],
email=form.cleaned_data['email'],
password=form.cleaned_data['password'])
user.is_active = False
user.save()
#create activate code
uuid_code = str(uuid.uuid4()).replace("-", '')
activate_code = ActivateCode(code=uuid_code)
activate_code.save()
return HttpResponse(f"You have registered successfully with activate_code: {uuid_code}. \n"
"Please activate your account from your registered email.")
The error it throwed
IntegrityError at /user/register
NOT NULL constraint failed: user_activatecode.user_id
Request Method: POST
Request URL: http://127.0.0.1:8001/user/register
Django Version: 1.11.13
Exception Type: IntegrityError
Exception Value:
NOT NULL constraint failed: user_activatecode.user_id
How to solve such a problem?
Seems you are trying to insert null value in a field that don't accept it, in you ActivateCode Model its seems you have a foreign key related to the user, maybe you have to post it also. Try to pass the user to the ActivateCode call:
ActivateCode(code=code, user=user)