I've an existing project on Django 3.1 and I upgraded my project to Django 3.2. I created an app called payment on my project. But When I make migrations. It trow an error
AttributeError: 'TextField' object has no attribute 'db_collation'
from django.db import models
from django.conf import settings
from django.utils.translation import gettext_lazy as _
# Create your models here.
from simple_history.models import HistoricalRecords
class TransactionType(models.TextChoices):
CASH_IN = 'IN', _('Cash In')
CASH_OUT = 'OUT', _('Cash Out')
class TransactionMethod(models.TextChoices):
STUDENT_TR = 'STT', _('Student Transaction')
BANK_TR = 'BKT', _('Bank Transaction')
SCHOOL_TR = 'SLT', _('School Transaction')
Teacher_TR = 'TRT', _('Teacher Transaction')
DONATE_TR = 'DET', _('Donate Transaction')
class Payment(models.Model):
id = models.AutoField(primary_key=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name="created_by")
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name="updated_by")
transaction_amount = models.FloatField("Transaction amount")
transaction_type = models.CharField(max_length=3, choices=TransactionType.choices, default=TransactionType.CASH_IN,)
transaction_method = models.CharField(max_length=3, choices=TransactionMethod.choices, default=TransactionMethod.STUDENT_TR,)
transaction_note = models.CharField(null=True, blank=True, max_length=200)
is_approved = models.BooleanField(default=False)
is_approved_by_user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name="approved_by",
null=True,
blank=True)
created_at = models.DateTimeField(auto_now=True, blank=True, null=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
history = HistoricalRecords()
Full error message
File "manage.py", line 22, in <module>
main()
File "manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/core/management/base.py", line 89, in wrapped
res = handle_func(*args, **kwargs)
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/core/management/commands/makemigrations.py", line 150, in handle
ProjectState.from_apps(apps),
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/db/migrations/state.py", line 220, in from_apps
model_state = ModelState.from_model(model)
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/db/migrations/state.py", line 407, in from_model
fields.append((name, field.clone()))
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 512, in clone
name, path, args, kwargs = self.deconstruct()
File "/home/asad/PycharmProjects/amarschool/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 2173, in deconstruct
if self.db_collation:
AttributeError: 'TextField' object has no attribute 'db_collation'
A field is thus a fundamental piece in different Django APIs, notably, models and querysets. In models, a field is instantiated as a class attribute and represents a particular table column, see Models. It has attributes such as null and unique, and methods that Django uses to map the field value to database-specific values.
Avoid using null on string-based fields such as CharField and TextField. If a string-based field has null=True, that means it has two possible values for “no data”: NULL , and the empty string. In most cases, it’s redundant to have two possible values for “no data;” the Django convention is to use the empty string, not NULL.
Values from -2147483648 to 2147483647 are safe in all databases supported by Django. It uses MinValueValidator and MaxValueValidator to validate the input based on the values that the default database supports. The default form widget for this field is a NumberInput when localize is False or TextInput otherwise.
The only field included with Django where this is True is ManyToManyField. Boolean flag that is True if the field has a many-to-one relation, such as a ForeignKey; False otherwise. Boolean flag that is True if the field has a one-to-many relation, such as a GenericRelation or the reverse of a ForeignKey; False otherwise.
I had the same issue, but it was resolved by updating to the latest django-simple-history after seeing https://github.com/jazzband/django-simple-history/issues/813 as recommended above.
I had a custom field like this :
class CountryField(CharField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('max_length', 2)
kwargs.setdefault('choices', COUNTRIES)
super(CharField, self).__init__(*args, **kwargs)
def get_internal_type(self):
return "CharField"
I changed into :
class CountryField(CharField):
def __init__(self, *args, db_collation=None, **kwargs):
kwargs.setdefault('max_length', 2)
kwargs.setdefault('choices', COUNTRIES)
super().__init__(*args, db_collation, **kwargs)
def get_internal_type(self):
return "CharField"
And it solved the problem
yesterday I tried to migrate a project from Django 3.1.8 to 3.2 but got stuck with this very same problem. It seems collation mechanism option cannot be avoided in certains configurations. See https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/operations/
After a couple of hours trying to figure out a workaround I just got back to Django 3.1.8. I hope you'll find a quick solution for this problem.
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