Generate Django "unique_together" key with "id" field - python

Here is the model
class MyModel(models.Model):
id = models.CharField(max_length=10, primary_key=True)
password = models.CharField(max_length=25)
area = models.CharField(max_length=100, primary_key=True)
def __unicode__(self):
return "%s from %s" % (self.id, self.area)
class Meta:
unique_together = (("id", "area"),)
I am trying to generate a unique key using Django's built-in Id functionality without making Id as a primary key.
Possible?

I do not think you can have a primary key based on multiple column (cf. django doc : https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys).
Only unique_together will still work.
In case what you want is an auto incremented field which is not a primary key :
AutoField¶
class AutoField(**options)¶ 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. See Automatic primary key
fields.

Related

Is this the correct way of making primary keys in django?

class profiles(models.model):
customer_ID = models.IntegerField().primary_key
Is this the correct way of making a primary key in django??
The correct syntax for primary key is-:
class profiles(models.model):
customer_ID = models.IntegerField(primary_key=True)
No, That is not the correct way of making a primary key in Django, in fact you don't have to specify a Primary key for your model, because django will automatically add a field to hold the primary key for you.
In your settings.py file, you will find a line with:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
which will automatically creates an 'id' field in all of your models by default. The BigAutoField is a 64bit integer that automatically increments according to available ids from 1 to 9223372036854775807.
class Profile(models.Model):
customer_username = models.CharField(max_length=100)
customer_email = models.EmailField()
the Profile model will have three fields: id, customer_username, customer_email
but, in case you want to overide the primary key, let's say for instane by using UUIDs instead of regular ids, you can overide it as follows:
import uuid
class Profile(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4,editable=False)
customer_username = models.CharField(max_length=100)
customer_email = models.EmailField()
for more details, please refer to the django documentation: https://docs.djangoproject.com/en/4.0/ref/models/fields/#primary-key
Is this the correct way of making a primary key in django??
No. You use an AutoField [Django-doc] for a primary key, since then the values are dispatched by the database, so:
class profiles(models.model):
customer_ID = models.AutoField(primary_key=True, editable=False)
But you do not have to specify a primary key: if you do not specify one yourself, Django will add one with the name id to the model automatically.

How to insert Primary key using Django Models?

i have set Primary key in my Django Models and but When i am inserting data into MongoDB database ,the primary key is not inserted.by default Django is inseting primary key but in my case its not.i Don't know what i am Doing Wrong Here.i am using below code
My Model.py
class CategoryModel(models.Model):
id = models.AutoField(primary_key=True) #if i don't use this line,django should insert primary by default.i my other app its inserting by default
category_name = models.CharField(max_length=255)
when i insert data into my CategoryModel,the primary key is not inserted.i am using Following code to insert data
Views.py
CategoryModel.objects.create(
category_name =request.POST['category_name']
)
Here,category_name is inserted but Primary key is not inserted.I don't know what is the issue.i Will be thankful if any one can help me with this issue.
a = CategoryModel()
a.category_name = request.POST['category_name']
a.save()
and ID you must use some other name for id because id is default django field
id_out = models.BigAutoField(primary_key=False, db_index=True, unique=True, editable=False)
Depends on what kind of id you're looking for, I typically use uuid4:
from uuid import uuid4
from django.db import models
def gen_uuid() -> str:
"""Return a str representation of a uuid4"""
return str(uuid4())
class CategoryModel(models.Model):
uid = models.CharField(
unique=True,
primary_key=True,
default=gen_uuid,
max_length=36,
help_text="Example: c8daa3ac-3dd0-44e9-ba2a-b0cbd1c8d8ae.",
)
category_name = models.CharField(max_length=255)
This allows to customize your ID. However if you are sure to use UUID like above I'd recommend this implementation as it uses the proper field:
from uuid import uuid4
from django.db import models
class CategoryModel(models.Model):
uid = models.UUIDField(
unique=True,
primary_key=True,
default=uuid4,
help_text="Example: c8daa3ac-3dd0-44e9-ba2a-b0cbd1c8d8ae.",
)
category_name = models.CharField(max_length=255)
As it is explained by the Autofield doc, you do not need to set your id if you wish to have the default id behavior: Autofield
It should insert your id automatically if you don't specify anything.

Django IntegrityError while updating a record

I have a model with double columns as primary key. I do a filter on it and get the records I want, change a field and save it. As I know save will update the record and does not create a new instance of the model in db. so It should be all okay but I'm stuck with an integrityError Duplicate entry '10-2' for key 'PRIMARY' when I try to save the record
Here is the code snippet:
analysis = AnalysisResult.objects.filter(request=req.request_id)
for anal in analysis:
anal.analysisresult_path = some_string
anal.save() #this line is where the error occurs
And here is my model:
class AnalysisResult(models.Model):
analysisresult_path = models.CharField(db_column='analysisResult_path', max_length=255, blank=True,
null=True) # Field name made lowercase.
detectionresult_path = models.CharField(db_column='detectionResult_path', max_length=255, blank=True,
null=True) # Field name made lowercase.
targetcode = models.ForeignKey('TagetCode', models.DO_NOTHING,
db_column='targetCode_id') # Field name made lowercase.
request = models.ForeignKey('Request', models.DO_NOTHING, primary_key=True)
class Meta:
managed = False
db_table = 'analysis_result'
unique_together = (('request', 'targetcode'),)
Ah, yes, welcome to one of django's strongest opinions: all tables/models should have a single primary key field that can be used for updates. If you don't have this, you must write raw SQL for the update since save will assume that there is an implicit primary key field called id to use in the where clause.

Django - create unique key that contains other models field

I'm trying to create 'unique_together' meta for a model, but instead of two fields from the current model, one of them is a field of other model (which is a foreign key in the current model):
I want the 'Item' model to have unique_together that contains both its 'identifier' field and the Spec's container_id. a Spec is foreign key in 'Item'.
Tried something like this, but I get "Unresolved reference spec..."
class Spec(BaseModel):
title = models.CharField(max_length=200)
identifier = models.IntegerField(unique=True)
container = models.ForeignKey(Container, related_name='specs')
class Item(SubmittalsBaseModel, BaseModel, DirtyFieldsMixin):
title = models.CharField(max_length=200)
identifier = models.CharField(max_length=200, unique=True)
spec = models.ForeignKey(Spec, related_name='items')
class Meta:
container_id = spec.container
unique_together = ('identifier', 'container_id')
You can't do that.. (at least I think)..
The unique_together clause is directly translated to the SQL unique index. And you can only set those on columns of a single table, not a combination of several tables.
You can add validation for it yourself though, simply overwrite the validate_unique method and add this validation to it.
Docs: http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.validate_unique

Django Foreign Key automatically filled based off of another field on model

So I currently have an "Account" Model and "Account Comments" Model -- keep in mind, that I can't really control the scheme of the database, and I'm writing a wrapper around existing DB.
Under the AccountComments Model, there is a field called "Data". It is where the AccountComments actually are and I'm trying to basically create a foreign key on the Account model without actually having to redesign and add a "AccountComments" field on Account that holds the AccountID.
class Account(models.Model):
AccountID = models.AutoField(editable=False, db_column='AccountID', verbose_name='ID',
primary_key=True)
acctno = models.IntegerField(editable=True, unique=True, db_column='ACCTNO', verbose_name='Acct #', blank=True,
null=True) # Field name made lowercase.
accountComments = models.ForeignKey('accountComments',to_field='accountID',db_column='Data')
def __str__(self):
return str(self.acctno)
class Meta:
managed = False
db_table = 'Account'
class accountComments(models.Model):
accountCommentID = models.AutoField(db_column='AccountCommentID', primary_key=True) # Field name made lowercase.
accountID = models.IntegerField(db_column='AccountID') # Field name made lowercase.
EntryUserID = models.IntegerField(db_column='EntryUserID') # Field name made lowercase.
EntryStamp = models.DateTimeField(db_column='EntryStamp', ) # Field name made lowercase.
Data = models.TextField(db_column='Data') # Field name made lowercase.
guid = models.CharField(db_column='guid', max_length=255) # Field name made lowercase.
class Meta:
managed = False
db_table = 'AccountComment'
ultimately, want accountComments on the Account Model to use 'AccountID' to do a lookup onto accountComments.accountID and then provide back 'Data'.
I know that I can use
def accountComments(self):
return str(accountComment.objects.get(accountID = self.AccountID).Data)
but I want it to work with Django Admin, so I need it to be an integrated part of the model.
Thanks if anyone can point me in the right direction.
You're trying to do too much with a foreign key. Following a foreign key in Django should return the model instance, not a particular field from the model instance.
The db_column should be the column in the Account table that stores the id, e.g.
accountComments = models.ForeignKey('accountComments',to_field='accountID',db_column='AccountID')
Then, to get the Data for a particular account instance, you would do:
account.accountComments.Data

Categories