Model:
class List(models.Model):
Lid = models.AutoField(primary_key=True)
Name = models.CharField(max_length=100)
addr1 = models.CharField(max_length=100)
addr2 = models.CharField(max_length=100)
City = models.CharField(max_length=40)
State = models.ForeignKey(State,blank=True, on_delete=models.DO_NOTHING, default=None,to_field="state",db_column="State") #,to_field="state",db_column="State"
Below is the error appears when tried to migrate,
IntegrityError(
django.db.utils.IntegrityError: The row in table 'list' with primary key '1' has an invalid foreign key: list.State contains a value '' that does not have a corresponding value in State.state.
How to fix this issue? I did add those 'blank=True' and on_delete=models.DO_NOTHING after searching for a solution in google, still no luck.
If you want have row from List and 1 row from State.
It can be o2o-key (don't matter which model), or you can use Foreign-key in List.
But: DB-Table State should have in your db_column="State" only unique keys.
If you want to have every row from List and some rows from State.
Foreign key should be in State model, not in List.
After that: On migration you should convert column list.state to value_type like in state.state.
For example you have type(list.state) = string and type(State.state) = integer. It can works without it, i know, but it is better to check it on migration.
if you have in list.state default=None, also you can convert every_list_row.state = '' to every_list_row.state = None, to avoid problem in future, on export etc.
If you receive ForeignObjectException - object not exists on list_row.state:
You can create something like that:
#property
def get_state(self):
return hasattr(list_row, 'state') and list_row.state or ''
and after that: list_row.get_state
Related
I want to filter Employee, only those that have a ForeignKey, how to do it? My solution does not returned any results.
Models.py
class Employee(models.Model):
name = models.CharField(max_length=200)
class ExperienceCategory(models.Model):
name = models.CharField(max_length=100, unique=True)
class Experience(models.Model):
user = models.ForeignKey(Employee, on_delete=models.CASCADE)
category = models.ForeignKey(ExperienceCategory, on_delete=models.CASCADE)
Views.py
experience_category = *ExperienceCategory object (1)*
#solution - final query
employee_query = Employee.objects.filter(experience__category = experience_category)
How to get employees who have a foreign key from Experience?
What you have should work just fine, as an example to reproduce that
first_employee = Employee.objects.create(name='First')
second_employee = Employee.objects.create(name='Second')
experience_category = ExperienceCategory.objects.create(name='sample_category')
Experience.objects.create(user=first_employee, category=experience_category)
Experience.objects.create(user=second_employee, category=experience_category)
employee_query = Employee.objects.filter(experience__category = experience_category)
employee_query
>>> <QuerySet [<Employee: Employee object (1)>, <Employee: Employee object (2)>]>
If you get an empty queryset it's because either there is no Experience instance with related category equal to experience_category in your database. To get the count of how many Experience instances matching this filter exist in your database you can run
Experience.objects.filter(category=experience_category).count()
In the case I provided it would return 2. Check first that this method returns a number greater than 0. If it returns 0 you should create some Experience instances first with the corresponding category.
can someone help me and teach me what happens?
For me not to make mistakes again?
I want to bind a foreign key (class category) to my course class. And I did something that doesn't allow me to get out of it.
Error: django.db.utils.IntegrityError: The row in table 'courses_course'
with primary key '3' has an invalid foreign key:
courses_course.category_id contains a value 'outros' that does not have a
corresponding value in courses_category.id.
CATEGORY = [('eng','ENGENHARIA'),('prog','PROGRAMAÇÃO'),('hum','HUMANAS'),('saude','SAÚDE'),
('outros','OUTROS')] // i'm from brazil
class Category(models.Model):
title_category = models.CharField('Nome da Categoria', max_length= 63 , choices = CATEGORY )
class Course(models.Model):
title = models.CharField('Nome', max_length= 100)
slug = models.SlugField('Atalho',max_length=50)
description = models.TextField('Descricao',blank = True)
follows = models.IntegerField(default = 0) //allows negative numbers, I know. I'll fix it ...
imagem = models.ImageField(upload_to = 'courses/images',verbose_name= 'Imagem',
null=True, blank = True)
category = models.ForeignKey('Category', on_delete = models.CASCADE)
created_at = models.DateTimeField('Criado em',auto_now_add = True )
updated_at= models.DateTimeField( 'Atualizado em', auto_now = True )
Does anyone imagine another structure or class that allows you to create educational courses / videos that have categories? Or am I on the right track for a beginner?
The only thing I can guess with the information you gave (you didn't say WHEN you get this error) is that you tried to do something such as :
my_course.category = 'outros'
my_course.save()
Which is incorrect since it isn't a Category object. A ForeignKey field must refer to an object of type to which you point to.
category = Category.objects.create(title_category='outros')
my_course.category = category
my_course.save()
This would work since you give a reference to a Category object in your Course object.
Do not hesitate to read the documentation about ForeignKey fields again.
I'm having difficulty assigning a title to the UserService model, which is a foreign key to another model.
models.py
class IndustryService(models.Model):
industryname = models.ForeignKey(Industry, on_delete=models.CASCADE)
title = models.CharField(max_length=120)
class UserService(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.ForeignKey(IndustryService, on_delete=models.CASCADE)
Here is the portion of code within the view that is failing:
industryservices = IndustryService.objects.filter(industryname=industry)
for service in industryservices:
try:
qs = UserService.objects.get(user=user, title=service.title)
except:
userserv = UserService.objects.create(user=request.user)
userserv.title = service
userserv.save()
The error that I'm getting is as follows:
NOT NULL constraint failed: accounts_userservice.title_id
Based on my testing, the way in which I'm assigning the value to the 'title' foreign key field is wrong (i.e. these 2 lines of code).
service2 = IndustryService.objects.get(title=service.title)
userserv.title = service2
Any thoughts on how I can fix this? Thanks!
You're doing two updates, unnecessarily. Either create the item in one go:
userserv = UserService.objects.create(user=request.user, title=service)
or instantiate without saving and then save at the end:
userserv = UserService(user=request.user)
userserv.title = service
userserv.save()
Maybe I misunderstand the purpose of Django's update_or_create Model method.
Here is my Model:
from django.db import models
import datetime
from vc.models import Cluster
class Vmt(models.Model):
added = models.DateField(default=datetime.date.today, blank=True, null=True)
creation_time = models.TextField(blank=True, null=True)
current_pm_active = models.TextField(blank=True, null=True)
current_pm_total = models.TextField(blank=True, null=True)
... more simple fields ...
cluster = models.ForeignKey(Cluster, null=True)
class Meta:
unique_together = (("cluster", "added"),)
Here is my test:
from django.test import TestCase
from .models import *
from vc.models import Cluster
from django.db import transaction
# Create your tests here.
class VmtModelTests(TestCase):
def test_insert_into_VmtModel(self):
count = Vmt.objects.count()
self.assertEqual(count, 0)
# create a Cluster
c = Cluster.objects.create(name='test-cluster')
Vmt.objects.create(
cluster=c,
creation_time='test creaetion time',
current_pm_active=5,
current_pm_total=5,
... more simple fields ...
)
count = Vmt.objects.count()
self.assertEqual(count, 1)
self.assertEqual('5', c.vmt_set.all()[0].current_pm_active)
# let's test that we cannot add that same record again
try:
with transaction.atomic():
Vmt.objects.create(
cluster=c,
creation_time='test creaetion time',
current_pm_active=5,
current_pm_total=5,
... more simple fields ...
)
self.fail(msg="Should violated integrity constraint!")
except Exception as ex:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
self.assertEqual("An exception of type IntegrityError occurred.", message[:45])
Vmt.objects.update_or_create(
cluster=c,
creation_time='test creaetion time',
# notice we are updating current_pm_active to 6
current_pm_active=6,
current_pm_total=5,
... more simple fields ...
)
count = Vmt.objects.count()
self.assertEqual(count, 1)
On the last update_or_create call I get this error:
IntegrityError: duplicate key value violates unique constraint "vmt_vmt_cluster_id_added_c2052322_uniq"
DETAIL: Key (cluster_id, added)=(1, 2018-06-18) already exists.
Why didn't wasn't the model updated? Why did Django try to create a new record that violated the unique constraint?
The update_or_create(defaults=None, **kwargs) has basically two parts:
the **kwargs which specify the "filter" criteria to determine if such object is already present; and
the defaults which is a dictionary that contains the fields mapped to values that should be used when we create a new row (in case the filtering fails to find a row), or which values should be updated (in case we find such row).
The problem here is that you make your filters too restrictive: you add several filters, and as a result the database does not find such row. So what happens? The database then aims to create the row with these filter values (and since defaults is missing, no extra values are added). But then it turns out that we create a row, and that the combination of the cluster and added already exists. Hence the database refuses to add this row.
So this line:
Model.objects.update_or_create(field1=val1,
field2=val2,
defaults={
'field3': val3,
'field4': val4
})
Is to semantically approximately equal to:
try:
item = Model.objects.get(field1=val1, field2=val2)
except Model.DoesNotExist:
Model.objects.create(field1=val1, field2=val2, field3=val3, field4=val4)
else:
item = Model.objects.filter(
field1=val1,
field2=val2,
).update(
field3 = val3
field4 = val4
)
(but the original call is typically done in a single query).
You probably thus should write:
Vmt.objects.update_or_create(
cluster=c,
creation_time='test creaetion time',
defaults = {
'current_pm_active': 6,
'current_pm_total': 5,
}
)
(or something similar)
You should separate your field:
Fields that should be searched for
Fields that should be updated
for example:
If I have the model:
class User(models.Model):
username = models.CharField(max_length=200)
nickname = models.CharField(max_length=200)
And I want to search for username = 'Nikolas' and update this instance nickname to 'Nik'(if no User with username 'Nikolas' I need to create it) I should write this code:
User.objects.update_or_create(
username='Nikolas',
defaults={'nickname': 'Nik'},
)
see in https://docs.djangoproject.com/en/3.1/ref/models/querysets/
This is already answered well in the above.
To be more clear the update_or_create() method should have **kwargs as those parameters on which you want to check if that data already exists in DB by filtering.
select some_column from table_name where column1='' and column2='';
Filtering by **kwargs will give you objects. Now if you wish to update any data/column of those filtered objects, you should pass them in defaults param in update_or_create() method.
so lets say you found an object based on a filter now the default param values are expected to be picked and updated.
and if there's no matching object found based on the filter then it goes ahead and creates an entry with filters and the default param passed.
I apologize in advance if my question has already been there, but I have not found.
there is a model:
class Artikul_cabinets(models.Model):
artikul_cabinets = models.CharField(verbose_name="Артикул шкафа", max_length=20)
title_cabinets = models.CharField(verbose_name="Описание шкафа", max_length=200)
width_cabinets = models.ManyToManyField(Width_cabinets)
depth_cabinets = models.ManyToManyField(Depth_cabinets)
unit_cabinets = models.ManyToManyField(Unit_cabinets)
weight_cabinets = models.ManyToManyField(Weight_cabinets)
type_cabinets = models.ForeignKey(Type_cabinets, default=1)
color_cabinets = models.ForeignKey(Color_cabinets)
glass_cabinets = models.ManyToManyField(Glass_cabinets)
class Meta:
verbose_name_plural = "Артикул шкафа"
def __str__(self):
return self.artikul_cabinets
It is necessary to make the selection on the field
glass_cabinets = models.ManyToManyField(Glass_cabinets)
The selection is done as follows
data = Artikul_cabinets.objects.filter(Q(glass_cabinets=perf) &
Q(glass_cabinets=glass)
perf and glass the variables with different values.
And I returned to my empty QuerySet, although the database element with the parameters 'perf' and 'glass' are present in the record.
Tell me what I'm doing wrong.
also tried:
data = Artikul_cabinets.objects.filter(Q(glass_cabinets=perf),
Q(glass_cabinets=glass)
and also did not work, though if you put the operator '|' the conditions or work out correctly.
So I think you should do Artikul_cabinets.objects.filter(glass_cabinets=perf).filter(glass_cabinets=glass)
check How to filter model results for multiple values for a many to many field in django