Id field in Model Django - django

I always get a primary column as Id in the Django model. Is there any possibility to change. For ex. for City table I want to have a Primary Key column as city_id.

city_id = models.AutoField(primary_key=True)

The answer is YES,
Something like this:
city_id = models.PositiveIntegerField(primary_key=True)
Here, you are overriding the id. Documentation here
If you’d like to specify a custom primary key, just specify primary_key=True on one of your fields. If Django sees you’ve explicitly set Field.primary_key, it won’t add the automatic id column.
Alternatively, You can always define a model property and use that . Example
class City(models.Model)
#attributes
#property
def city_id(self):
return self.id
and access it as city.city_id where you would normally do city.id

By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
This is an auto-incrementing primary key.
So for your case is:
city_id = models.AutoField(primary_key=True)

Ofcourse, you can.
city_id = models.BigIntegerField(primary_key=True)

Related

How to make a model parameter unique by a other parameter in Django?

I want my id field to be unique per each customer field. Just like the option unique_for_date from Django (https://docs.djangoproject.com/en/1.11/ref/models/fields/#unique) but in this case, not date but customer.
class Sample(NGObject):
id = models.CharField(max_length=128, null=True, blank=False)
customer = models.ForeignKey(Customer, related_name="blood_samples", on_delete=models.SET(get_default_customer))
I believe this should be done, before the save() method?
When a User writes the wrong ID (that already exists) I would also like to present the information in the Admin Form just like it would for normal unique error.
class Meta:
unique_together = ('sample_id', 'customer',)
This has done the trick :)

Generating unique id in a model with prefix of field value of another model

I created two models "Category" and "Item". There is a field "title" in category model, I want the value of the "title field" to be prefix of my "unique id field" in Item module can anyone suggest me a solution for this problem.
Thank you
The default id in django models is something like this:
class Custom(models.Model):
id = models.IntegerField(primary_key=True, editable=False)
So, the possible way to achieve the requirement is to change the IntegerField to CharField.
Technically you can use "String PK Field" But, you should be aware of the problems/performance issues if you are going to use that. more: Strings as Primary Keys in SQL Database
If you still really wish to migrate to String PKs:
First you need to use the CharField instead of IntegerField and override the save() method of model
from django.db.models import Max
class Item(models.Model):
id = models.CharField(primary_key=True, editable=False)
prefix = models.CharField(max_length=100)
def save(self, **kwargs):
if not self.id:
max = Item.objects.aggregate(id_max=Max('id'))['id_max']
self.id = "{}{:05d}".format(self.prefix, max if max is not None else 1)
super().save(*kwargs)
According to this: Django generate custom ID

Setting default value of field in model to another model instance

Model
class SlackPermission(models.Model):
#fields
class GithubPermission(models.Model):
#fields
class Employee(models.Model):
#fields
slack_permission = models.OneToOneField(SlackPermission, on_delete=models.CASCADE, related_name='Slack',default=SlackPermission.objects.get(pk=1))
github_permission = models.OneToOneField(GithubPermission, on_delete=models.CASCADE, related_name='Github',default=GithubPermission.objects.get(pk=1))
Error:
ValueError: Cannot serialize: <GithubPermission: GithubPermission object (1)>
There are some values Django cannot serialize into migration files.
I am creating API just to create Employee. Where there is not option of giving slackpermissions and githubpermissions. How do I give default value in there?
The problem is that the default is calculated immediately, and for migrations, it can not really serialize that.
That bing said, it is not very useful to do this anyway. You can just pass the primary key as default value. This is specified in the documentation on the default=… parameter [Django-doc]:
For fields like ForeignKey that map to model instances, defaults should be the value of the field they reference (pk unless to_field is set) instead of model instances.
So we can write this as:
class Employee(models.Model):
full_name = models.CharField(max_length=100)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
slack_permission = models.OneToOneField(
SlackPermission,
on_delete=models.CASCADE,
related_name='Slack',
default=1
)
github_permission = models.OneToOneField(
GithubPermission,
on_delete=models.CASCADE,
related_name='Github',
default=1
)
Note that you should ensure that there exists an object with that primary key. Therefore it might not be ideal to do that.
The issue here is that you are attempting to set a field value to an object instance. So your default value should be just 1 if you are certain of the pk.
Also, I am not sure the advantage of creating two separate models for these permission values. Seems like they can just be fields in your employee model. Seems like these permissions share identical fields as well which will allow you to flatten them a bit.

Django: Does "primary_key=True" also mean "unique"?

Hello i am testing Django authentication and nesting user data. I created a simple MyProfil model for my users. I wanted to test making a custom id and set the primary_key=True as id = models.UUIDField.
models.py
class MyProfil(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
owner = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
aboutme = models.TextField(max_length=300, blank=True)
city = models.TextField(max_length=300, blank=True)
so far everything works in my favor but i have a question, that i could not answer myself even after reading the django doc.
Question
Does primary_key=True on my id Field also mean unique or do i have to declare it?
Yes. Since a primary key means a value that can uniquely identify an object. In the documentation on the primary_key parameter, we see:
Field.primary_key
If True, this field is the primary key for the model.
If you don’t specify primary_key=True for any field in your model,
Django will automatically add an AutoField to hold the primary key,
so you don’t need to set primary_key=True on any of your fields
unless you want to override the default primary-key behavior. For
more, see Automatic primary key fields.
primary_key=True implies null=False and unique=True. Only one primary key is allowed on an object.

Django view retrieve model id of instance just created

I have a simple scenario trying to retrieve the id/pk of a model instance created in a view. The model instance is creating fine however the id/pk is returning "None". I thought I was following the code as laid out in the latest documentation but I must be doing something wrong.
Models.py
class Userdownloads(models.Model):
id = models.IntegerField(primary_key=True)
created_by = models.ForeignKey(User,on_delete=models.DO_NOTHING, related_name='Download_created_by',null=True,blank=True)
created_date = models.DateTimeField(auto_now_add=True)
Views.py
d = Userdownloads(created_by=request.user)
d.save()
print(d.id)
Ive tried both d.id and d.pk
Can anybody help my see where I am going wrong? Any help is much appreciated!
On save call of the given example should throw an error like this:
null value in column "id" violates not-null constraint
So, here the id field should be AutoField. For example:
id = models.AutoField(primary_key=True)
From the documentation,
AutoField
An IntegerField that automatically increments according to available IDs. You usually won’t need to use this directly; a primary
key field will automatically be added to your model if you don’t
specify otherwise
You don't have to specify id on django models because it will automatically create for you.
class Userdownloads(models.Model):
created_by = models.ForeignKey(User,on_delete=models.DO_NOTHING, related_name='Download_created_by',null=True,blank=True)
created_date = models.DateTimeField(auto_now_add=True)
Here is the link to the models
If it give you None then it has not been saved to the database yet.