In my django model I would like to set the field unique_id
below to be the primary key as this will be the field used in queries for the model. It satisfies unique=True
and null=False
. However as django sets an AutoField to primary key in the background I'm unsure whether a CharField (which uses a unique 3 character code) is suitable as a primary key or whether this will be sub-optimal?
class PaymentMethod(models.Model):
unique_id = models.CharField(max_length=3)
last_updated = models.DateTimeField(auto_now=True)
If you'd like to specify a custom primary key, 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. Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
Django does not support composite primary keys.
By default, Django adds an id field to each model, which is used as the primary key for that model. You can create your own primary key field by adding the keyword arg primary_key=True to a field. If you add your own primary key field, the automatic one will not be added.
CharField is generally used for storing small strings like first name, last name, etc. To store larger text TextField is used. The default form widget for this field is TextInput. CharField has one extra required argument: CharField.max_length. The maximum length (in characters) of the field.
There is nothing wrong with setting the CharField
to be a primary key, by changing the model to be:
class PaymentMethod(models.Model):
unique_id = models.CharField(max_length=3, primary_key=True)
last_updated = models.DateTimeField(auto_now=True)
In actual fact if the unique_id is the field you will be querying it makes perfect sense to use it. Your other options are to use your existing model but with unique=True
:
class PaymentMethod(models.Model):
unique_id = models.CharField(max_length=3, unique=True)
last_updated = models.DateTimeField(auto_now=True)
In this case your primary key will be an auto incrementing integer as you previously stated.
Another option depending on the number of records you are looking to store in the PaymentMethod
models; and where the data is used elsewhere within your application. Is too look into using a model choices field. The model choices field might be on your payments or order model (depends on your application and what you are trying to do). This removes the need for a foreignkey and potentially reduces the number of queries in your app.
It could look something like this:
class Payment(models.Model):
VISA = 'VIS'
CREDIT = 'CRE'
MASTER_CARD = 'MAS'
PAYPAL = 'PAL'
PAYMENT_OPTIONS= (
(VISA, 'Visa'),
(CREDIT, 'Credit Card'),
(MASTER_CARD, 'Master Card'),
(PAYPAL, 'Paypal')
)
items = models.ForeignKey(Item)
date = models.DateField(auto_now=True)
...
payment_method = models.CharField(max_length=3, choices=PAYMENT_OPTIONS, default=VISA)
The PAYMENT_OPTIONS
can be used to render dropdown boxes on the forms when using django model forms. Otherwise the users selection is limited to the options listed within this model.
This method would be a lot more efficient if you only have a small subset of PaymentMethod(s)
.
It's possible to use CharField
as primary key. You just have to mark the field as primary key.
field_name = models.CharField(primary_key=True, max_length=100)
But I wouldn't recommend it because:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With