I'm writing a website on Python, Django using MongoDB and Djongo (to connect Mongo with Django) and I want to be able to add and delete documents from the database using my website. But I have an error while doing it.
If I don't set primary key in my models then I can successfully add documents, but when try to delete have AssertionError (object can't be deleted because its id attribute is set to None), however when I check the database _ID field is there created automatically. If I do set primary key by primary_key = True in models.py I can successfully delete a document, but on insertion I got AssertionError (No exception message supplied).
Also, if primary key is not set, then I cannot access documents from admin panel, but can add them to the database (through admin panel); and if pk is set then from admin panel I can access, delete and edit, but cannot add a new document to the database.
This is my model:
class DevList(models.Model):
dev_num = models.CharField(max_length = 200 , primary_key = True)
dev_name = models.CharField(max_length = 200)
dev_descr = models.CharField(max_length = 200)
dev_type = models.CharField(max_length = 200)
If no pk is set, then I delete primary_key = True line
My view is simple post form and I use d.save() to save and d.delete() to delete.
Actually, Django by default provides an id field with every model which is by default set as primary key.
Now, when you can set other field as primary key by primary_key=True. But for smoother operation I will advice you to use unique=True on other fields.
dev_num = models.CharField(max_length = 200 , unique = True)
I had a similar problem using MongoDB + Django with the Djongo driver (cannot delete objects in the admin page of my website because the _id is not an integer but an ObjectID() wich is not recognized as a valid integer).
This is how I solved it (the quickest way) :
I set for my object an id with the models.PositiveIntegerField type and I use the primary_key argument with the True value) :
class MyObject(models.Model):
id = models.PositiveIntegerField(primary_key=True)
title = models.CharField(max_length=100)
other_field = models.TextField(blank=True)
def __str__(self):
return f"{self.title}"
This way, the _id of mongoDB is not used but the admin system still find a valid integer for the primary key. That has been tested succesfully, problem solved.
Related
I am getting this error while trying to save a model from the admin section using Django admin, this is the error Field 'object_id' expected a number but got 'id_b2cbfe2b1fd4313c'.. I am using django shortuuid package https://pypi.org/project/shortuuid/ to create id field in django, and i choose to use it because the inbuild UUID field keeps giving this error Django UUIDField shows 'badly formed hexadecimal UUID string' error? and the id looks like this id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True). What would be the problem witht the short uuid field.
Based on this, i quote:
If you filter on the ForeignKey, then Django will filter on the primary key of the target object, and that is normally an AutoField, unless you referred to another (unique) column, or defined another primary key as field.
But i dont know what the issue might be now
Models.py
class Channel(models.Model):
id = ShortUUIDField( length=16, max_length=40, prefix="id_", alphabet="abcdefg1234", primary_key=True,)
full_name = models.CharField(max_length=200)
user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True, related_name="channel")
Views.py
def channel_profile(request, channel_name):
channel = Channel.objects.get(id=channel_name, status="active")
context = {
"channel": channel,
}
return render(request, "channel/channel.html", context)
Your database is not sync with your migrations file, because your problem is easy to solve, Django is expecting an ID (integrer) and you are passing a string.
If you have not push your project into production you can delete the migration folder and migrate again, otherwise you need to update your migrations files to change the type for the UD field
Django ORM doesn't resolve id that generates in DB with special SQL trigger while record inserting.
When I'm saving model without ID it saves correctly and have ID in DB? but m.id returns me None.
class SomeModel(Model):
id = IntegerField(primary_key=True)
name = CharField(null=False, max=50)
m = SomeModel(name='asd')
m.save()
m.id # - None
How I can resolve autogenerated ID after saving? Or how I can rewrite save() method? Or maybe change field type?
I need to use my own trigger instead of IDENTITY!
Please read Django documentation. By default you don't need say to Django what is primary key. But if you wanna.
class SomeModel(Model):
id = models.AutoField(primary_key=True, db_index=True)
name = CharField(null=False, max=50)
I am creating the object of a model using custom create method create_actor like this:
class ActorsManager(models.QuerySet):
def create_actor(self, email,
actortype,
locationid,
primaryphone, actoruniversalid):
actor = self.model(email=email,
actortype=actortype,
locationid = locationid,
primaryphone=primaryphone, actoruniversalid= actoruniversalid)
actor.save(using='gpr')
return actor
actor_entry = Actors.objects.using('gpr').create_actor(email='', actortype=1, locationid = location_entry,primaryphone='', actoruniversalid= new_bluenumber)
I am not getting the recently created object in actor_entry variable,
may be i am doing something wrong, please help.
I'm using a before insert SQL trigger to generate uuid as pk(CharField here) in the database, so the object does have a pk (generated by the database) before its saved.
Actors Model
class Actors(models.Model):
actorid = models.CharField(db_column='ActorID', primary_key=True, max_length=255) # Field name made lowercase.
actoruniversalid = models.CharField(db_column='ActorBluenumber', unique=True, blank=True, null=True, max_length=254)
......
......
objects = ActorsManager.as_manager()
class Meta:
managed = False
db_table = 'actors'
Unless you created your actors table by hand, the ActorID will not automatically be set. Depending on your database backend, None may be treated the same as the empty string, and as such could be a valid primary key. I believe Django takes special measures to update the row if one exists with the same primary key unless you specify forceinsert=True when invoking save()
As #knbk pointed out that only an AutoField can set the pk to an object and so the pythonic logic to retrieve the pk is not executed when its not an AutoField and so django doesn't know about it.
After searching the django documentation I found an alternative to AutoField for UUIDs,an UUIDField which is best suited for my Use Case.
actorid = models.UUIDField(db_column='ActorID', primary_key=True, editable=False, default=uuid.uuid4)
So now the django does know of the pk and thus the object is retrieved after being saved.
Thank you all for the help.
I have a project where a user can review a service. Whenever I try to write a review with the same user twice, I get an Integrity error:
duplicate key value violates unique constraint "reviews_review_user_id_key" DETAIL: Key (user_id)=(7) already exists.
I'm not too sure why I am getting this error. Is it because there should be a many-to-many relation between users and reviews?
The review model looks like this:
class Review(models.Model):
user = models.ForeignKey(User)
service = models.ForeignKey('services.Service')
rating_value = models.IntegerField(default = 0)
review_text = models.CharField(max_length = 500, default= "null")
pub_date = models.DateTimeField(default=timezone.now,blank=True)
def __str__(self): # __unicode__ on Python 2
return self.service_name
It appears that you have removed the unique constraint in the models.py, but the unique constraint still exists on the database table. This has happened to me before and I was able to remove the constraint from the table through ./manage.py dbshell and everything worked as expected.
Not sure which db you're using, but for postgres it would be: ALTER TABLE your_table DROP CONSTRAINT reviews_review_user_id_key;
Give that a shot, hope it helps.
I have my User model set up with no primary key so that the automatic id will be used instead. However, when I try to access it using Django's "_set" notation when it is referenced through a foreign key:
def postDetails(request, pk)
post = Post.objects.get(pk=pk)
if post.user_set.all(): # Errors on this line
[...]
I get an error from MySQL:
OperationalError at /webApp/postDetail/42/ (1054,
"Unknown column 'user.id' in 'field list'")
What am I doing wrong? Should I be accessing it differently? Are there limitations to the automatic id?
Model for reference:
class Post(models.Model):
name = models.CharField(max_length=128)
blog = models.ForeignKey('Blog')
active = models.BooleanField(blank=True)
created_date = models.DateTimeField()
class Meta:
managed = False
db_table = 'post'
def __unicode__(self):
return self.name
class User(models.Model):
level = models.ForeignKey(Level)
post = models.ForeignKey(Post)
name = models.CharField(max_length=64)
note = models.CharField(max_length=4096)
active = models.BooleanField(blank=True, default=True)
class Meta:
managed = False
db_table = 'user'
Something else that I thought to include: I did run syncdb before running this.
EDIT : wrong answer. check comments below
The problem is that you have managed set to False. According to the documentation
If False, no database table creation or deletion operations will be performed for this model. This is useful if the model represents an existing table or a database view that has been created by some other means. This is the only difference when managed=False. All other aspects of model handling are exactly the same as normal. This includes
Adding an automatic primary key field to the model if you don’t declare it. To avoid confusion for later code readers, it’s recommended to specify all the columns from the database table you are modeling when using unmanaged models.
You will need to define the primary key as this is not done by default anymore.
Not 100% sure, but I think even though Django will add the id field to the model class, that field will not propagate to the DB with syncdb.
One way to try it would be to rename the existing User table, run syncdb and see if the User table is created. If not (which is likely because of the managed flag) try again with managed=True. If the id field appears in this case then my guess is you'll have to add it manually to the User table with the same parameters as the automatically created one.