I'm trying to associate Comment with User models, but somehow the field is not being created in the database. When I try to access the page, the following error is shown:
(1054, "Unknown column 'user_comments.user_id' in 'field list'")
These are in the models.py:
class User(models.Model):
username = models.CharField(max_length=128)
password = models.CharField(max_length=128)
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.CharField(max_length=128)
date_joined = models.DateField(auto_now_add=True)
class Meta:
db_table = 'auth_user'
ordering = ('date_joined',)
class Comment(models.Model):
user = models.ForeignKey('auth.User', related_name='comments', on_delete=models.CASCADE)
content = models.CharField(max_length=256)
date_created = models.DateField(auto_now_add=True)
class Meta:
db_table = 'user_comments'
ordering = ('date_created',)
def __str__(self):
return self.content
def save(self, *args, **kwargs):
content = self.content
super(Comment, self).save(*args, **kwargs)
If I name the user variable to user_id, an error saying user_id_id wasn't found will show upon creating a new Comment in the admin panel.
** Update **
I dropped the whole database and I removed the db_table options, and thus user_id has been created. But now, upon creation of a new Comment, the following:
IntegrityError at /admin/api/comment/add/
(1452, 'Cannot add or update a child row: a foreign key constraint fails (`softwarestore`.`api_comment`, CONSTRAINT `api_comment_user_id_14315666_fk_api_user_id` FOREIGN KEY (`user_id`) REFERENCES `api_user` (`id`))')
Have you tried simply replacing following:
user = models.ForeignKey('auth.User', related_name='comments', on_delete=models.CASCADE)
with
user = models.ForeignKey(User, related_name='comments', on_delete=models.CASCADE)
and run makemigrations?
Related
Each of my mapped class contains created_by and updated_by audit properties that I would like to set automatically upon INSERT and UPDATE of respective objects.
class User(Base):
__tablename__ = 'user'
id = Column(BigInteger, primary_key=True)
name = Column(Text, nullable=False)
...
class Address(Base):
__tablename__ = 'address'
id = Column(BigInteger, primary_key=True)
street = Column(Text, nullable=False)
...
created_by = Column(BigInteger) # references user.id
updated_by = Column(BigInteger) # references user.id
...
Is there a way to handle this centrally in SQLAlchemy? I looked at the events but it appears it needs to be setup for every single mapped class individually (note the SomeClass in the decorator).
#event.listens_for(SomeClass, 'before_insert')
def on_insert(mapper, connection, target):
target.created_by = context["current_user"] # I want to be able to do this not just for 'SomeClass' but for all mapped classes
#event.listens_for(SomeClass, 'before_update')
def on_update(mapper, connection, target):
target.updated_by = context["current_user"] # I want to be able to do this not just for 'SomeClass' but for all mapped classes
One solution here is to use the default parameters in the Column class provided by sqlalchemy. You can actually pass a callable to both default (to execute when first created) and onupdate to execute whenever updated.
def get_current_user():
return context["user"].id
class Address(Base):
__tablename__ = 'address'
...
created_by = Column(default = get_current_user)
updated_by = Column(default = get_current_user, onupdate=get_current_user)
Managed to figure it out, though somewhat concerned about using a dunder method __subclasses__() on declarative_base. If there is a better alternative do suggest.
def on_insert(mapper, connection, target):
target.created_by = context["user"].id
target.updated_at = datetime.utcnow()
def on_update(mapper, connection, target):
target.updated_by = context["user"].id
target.updated_at = datetime.utcnow()
Base.metadata.create_all()
mapped_classes = Base.__subclasses__()
for mapped_class in mapped_classes:
event.listen(mapped_class, 'before_insert', on_insert)
event.listen(mapped_class, 'before_update', on_update)
The context being referred to here is actually starlette-context
I have two models: shipping model that is having a foreign key carrierID and it is referencing the other model Carrier. When I want to add a new shipping I am getting the aforementioned error. What I know, I don't have carrierID_id field but I don't why I getting this error.
Here is the structure of my models:
class Carrier(models.Model):
class Meta:
verbose_name_plural='carriers'
carrierID=models.CharField(max_length=15, unique=True)
carrierName=models.CharField(max_length=50)
carrierTelephoneNumber=models.CharField(max_length=14)
carrierAddress=models.TextField()
def __str__(self):
return '{}{}{}{}'.format(self.carrierID,' ' , self.carrierName,' ', self.carrierTelephoneNumber,' ',self.carrierAddress)
class Shipping(models.Model):
shippingID = models.AutoField(primary_key=True)
carrierID = models.ForeignKey(Carrier, on_delete=models.CASCADE)
shippingDate = models.DateTimeField()
productName=models.CharField(max_length=30)
shippingAddress = models.TextField()
sendTo = models.CharField(max_length=50)
shippingStatus = models.BooleanField(default=False)
promisedDate=models.DateTimeField()
comment = models.TextField()
The structure of shippingForm is as below:
class ShippingForm(forms.ModelForm):
carrier = Carrier.objects.only('carrierID')
print(carrier)
carrierID = forms.ModelChoiceField(carrier)
shippingDate = forms.DateTimeField(required=False)
productName = forms.CharField(max_length=30, required=False)
shippingAddress = forms.Textarea()
sendTo = forms.CharField(max_length=50)
shippingStatus = forms.BooleanField(required=False)
promisedDate = forms.DateTimeField(required=False)
comment = forms.Textarea()
class Meta:
model=Shipping
fields=('carrierID','shippingDate', 'productName','shippingAddress', 'sendTo','shippingStatus','promisedDate', 'comment',)
Below are my MySQL tables:
Here is the SQL of the shipping.
create table pages_shipping(shippingID int auto_increment,
carrierID int(11),
shippingDate date,
prductName varchar(50),
shippingAddress text,
sendTo varchar(50),
shippingStatus boolean,
promisedDate date,
comment text,
primary key(shippingID),
foreign key(carrierID) REFERENCES pages_Carrier(id) ON DELETE CASCADE);
Please assist
I got what is happening. It is because when I run py manage.py makemigrations command, the field carrierID is not added. Unfortunately, I don't know to force Django to add it
I have the following tables in models.py:
class Part(models.Model):
partno = models.CharField(max_length=50, unique=True)
partdesc = models.CharField(max_length=50, default=None, blank=True, null=True)
class Price(models.Model):
part = models.ForeignKey(Part, on_delete=models.CASCADE, null=True)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
qty = models.IntegerField(default=1)
price = models.DecimalField(max_digits=9, decimal_places=2)
currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
datestart = models.DateTimeField(auto_now_add=True, blank=False, null=False)
class Meta:
unique_together = (('supplier', 'part'),)
This is properly working. The problem is I have many part numbers which are their replacements. For example part 1001-01, 1001-02, 1001-03 are all the same part. Still, I have all of them in my Part table.
I need to match them in another table, so I don't need to enter price for each of them separately. There must be a unique key representing all of these three items.
Question: How do I setup a "part number match table" and have a foreign key to this table in my Price table?
(Rest is optional to read which are my opinions/problems so far, might help though)
1: I tried to setup the table like this:
class PartMatch(models.Model):
id = models.IntegerField(primary_key=True, unique=False, null=False, db_index=True)
part = models.ForeignKey(Part, unique=False, on_delete=models.CASCADE)
I don't get an error while migrating but when I try to use the same id for PK, it doesn't allow me.
2: I left the pk alone and tried to setup another field to match parts:
class PartMatch(models.Model):
part = models.ForeignKey(Part, on_delete=models.CASCADE)
partmatchid = models.IntegerField(null=True, unique=False, db_index=True)
I don't get any error while migrating but when I try to use partmatchid as a foreign key in my Price table like this:
partmatch = models.ForeignKey(PartMatch, to_field="partmatchid",
db_column="partmatchid",
on_delete=models.CASCADE)
I get an error saying foreign key must be unique while migrating.
Well in this case I am out of solutions. I wonder how you guys handle this?
Your Part model can have a foreign key to PartMatch, not the other way around.
Your model can be Part *<-->1 PartMatch and PartMatch 1<-->1 Price
For example:
class Price(models.Model):
price = models.DecimalField(max_digits=9, decimal_places=2)
class PartMatch(models.Model):
price = models.OneToOneField(Price, primary_key=True)
class Part(models.Model):
partno = models.CharField(max_length=50, unique=True)
partMatch = models.ForeignKey(PartMatch)
If you want to get all parts with some price, some_price.partmatch.part_set.all() will do the job.
When I update/delete some content through views.py file i.e via the website, everything works fine but when I try to update some data through admin panel i get this error:
IntegrityError at /admin/library/student/
(1452, 'Cannot add or update a child row: a foreign key constraint fails (kt2.django_admin_log, CONSTRAINT django_admin_log_user_id_52fdd58701c5f563_fk_auth_user_id FOREIGN KEY (user_id) REFERENCES auth_user (id))')
where kt2 is the name of my database.
Please help and also let me know if you need the code.
models.py
# Create your models here.
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class Student(AbstractUser):
roll_number = models.CharField(max_length=30,unique=True)
student_name = models.CharField(max_length=200)
branch = models.CharField(max_length=20)
sem = models.IntegerField()
pic = models.ImageField(null=True,blank=True)
due_fine = models.IntegerField(default=0)
USERNAME_FIELD='roll_number'
REQUIRED_FIELDS=['username','email']
def __str__(self):
return self.student_name
class Author(models.Model):
author_name = models.CharField(max_length=200,primary_key=True)
def __str__(self):
return self.author_name
class Quantity(models.Model):
q_id=models.AutoField(primary_key=True)
book_name=models.CharField(max_length=200)
list_of_authors=models.ManyToManyField(Author)
qty = models.IntegerField(default=1)
class Meta:
verbose_name_plural = 'Quantity'
# unique_together=(('book_name','list_of_authors'),)
def __str__(self):
return self.book_name
class LastFiveIssues(models.Model):
lfi_id=models.AutoField(primary_key=True)
one_st=models.CharField(max_length=30,blank=True,null=True)
two_st=models.CharField(max_length=30,blank=True,null=True)
three_st=models.CharField(max_length=30,blank=True,null=True)
four_st=models.CharField(max_length=30,blank=True,null=True)
five_st=models.CharField(max_length=30,blank=True,null=True)
issue_one_date=models.DateField(blank=True,null=True)
issue_two_date=models.DateField(blank=True,null=True)
issue_three_date=models.DateField(blank=True,null=True)
issue_four_date=models.DateField(blank=True,null=True)
issue_five_date=models.DateField(blank=True,null=True)
return_one_date=models.DateField(blank=True,null=True)
return_two_date=models.DateField(blank=True,null=True)
return_three_date=models.DateField(blank=True,null=True)
return_four_date=models.DateField(blank=True,null=True)
return_five_date=models.DateField(blank=True,null=True)
class Meta:
verbose_name_plural='last five issues'
class Publisher(models.Model):
publisher_name = models.CharField(max_length=200,primary_key=True)
def __str__(self):
return self.publisher_name
class Book(models.Model):
last_five_issues=models.OneToOneField(LastFiveIssues)
publisher_book=models.ForeignKey(Publisher)
authors = models.ForeignKey(Quantity)
student = models.ForeignKey(Student)
book_id = models.CharField(primary_key=True,max_length=30)
is_issued = models.BooleanField(default=False)
dep_book = models.CharField(max_length=20)
book_name = models.CharField(max_length=200)
date_of_issue = models.DateField(default = '1900-1-1')
return_date = models.DateField(default='1900-1-1')
book_added_on = models.DateField(default='1900-1-1')
placed_at_shelf=models.CharField(max_length=200,blank=True,null=True)
edition_of_book = models.IntegerField()
rare_book = models.BooleanField(default=False)
claim_one=models.CharField(max_length=30,blank=True,null=True)
claim_two=models.CharField(max_length=30,blank=True,null=True)
claim_three=models.CharField(max_length=30,blank=True,null=True)
def __str__(self):
return self.book_name
I'm using the the built in django admin site to save instances of a model that has a ManyToMany field. If I save, not update, a model in the admin site without setting a value for the ManyToMany field it saves fine. I can also come back and set the ManyToMany field after saving the model and that works. However, if I try to save a new instance of my model, Exercise, that has the ManyToMany field, Exercise.muscles, set I get the following error:
(1452, 'Cannot add or update a child row: a foreign key constraint fails
(vitality.projectvitality_exercise_muscles, CONSTRAINT exercise_id_refs_exercise_id_a5d4ddd6 FOREIGN KEY (exercise_id) REFERENCES projectvitality_exercise (exercise_id))')
My mysql tables are set to INNODB.
My models are as follows:
class Muscle(models.Model):
def format(self):
return "name:{0}:".format(self.name)
def __unicode__(self):
return unicode(self.name)
muscle_id = UUIDField(primary_key = True)
name = models.CharField(max_length=30, blank=False, default="")
medical = models.CharField(max_length=150, blank=True, default="")
description = models.TextField(blank=True, default="")
class Exercise(models.Model):
def format(self):
return "name:{0}".format(self.name)
def __unicode__(self):
return unicode(self.name)
ISOLATION_TYPE = "isolation"
COMPOUND_TYPE = "compound"
FULL_BODY_TYPE = "full"
EXERCISE_TYPES = (
(ISOLATION_TYPE, "Isolation"),
(COMPOUND_TYPE, "Compound"),
(FULL_BODY_TYPE, "Full Body")
)
UPPER_BODY_GROUP = "upper"
LOWER_BODY_GROUP = "lower"
GROUP_CHOICES = (
(UPPER_BODY_GROUP, "Upper Body"),
(LOWER_BODY_GROUP, "Lower Body")
)
exercise_id = UUIDField(primary_key=True)
name = models.CharField(max_length=30, default="", blank=False)
description = models.TextField(blank=True, default="")
group = models.CharField(max_length=255,
choices=GROUP_CHOICES,
blank=False,
default=UPPER_BODY_GROUP)
exercise_type = models.CharField(max_length=255,
choices=EXERCISE_TYPES,
blank=False,
default=ISOLATION_TYPE)
muscles = models.ManyToManyField('Muscle', blank=True, null=True)
class Meta:
verbose_name = "Exercise"
verbose_name_plural = "Exercises"
After several days of debugging I found the issue. In my code I use UUIDField, from django-extensions library, as a primary key. When saving a new instance of Exercise model it is able to generate, set and save the primary key. However, when saving a new instance of Exercise that has the ManyToMany field set, UUIDField isn't generated in time. This leads to the Django admin attempting to insert a null/empty primary key, the UUIDField in Exercise model, into the join table which triggers the Foreign Key constraint failure.