I created a dummy project just to test the new field JSONField of Django but the column doesn't not appear to be created (I am using Postgresql).
class Author(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()
slug = models.SlugField()
details = models.JSONField()
class Meta:
verbose_name = "Author"
def __str__(self):
return self.name
If i go to the database, the column is not created -- screenshot
When i go to the admin view page of the table Author i get the following error -- screenshot
The error in the admin panel is understandable: you cannot view a column that does not exist. Do you guys have the same error? I can't find this error with JSONField anywhere.
Thanks
Note: This is my first post.
EDIT I create all the fields in the same time. Migration file:
# Generated by Django 3.1.3 on 2020-11-20 10:35
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Author',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('description', models.TextField()),
('slug', models.SlugField()),
('details', models.JSONField()),
],
options={
'verbose_name': 'Author',
},
),
]
Migrated with sucess:
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Author
check that you migration was applied to the right database
Related
I did lot's of try, catch on this issue and basically still not find the core problem but this is what I got for now.
in the settings.py I am turning on the USE_TZ = True TIME_ZONE = 'UTC' and creating a model like below.
class Plan(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=100)
price = models.IntegerField()
description = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
when I try to makemigration for this is no problem. Here is the first migration file of Plan model
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Plan',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('code', models.CharField(max_length=100)),
('price', models.IntegerField()),
('description', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
),
]
Now, when I try to migrate this file. There are two table created in the DB. one for django_migrations and the other is Plan model. After running migrate command. error follows.
raise ValueError('Not naive datetime (tzinfo is already set)') ValueError: Not naive datetime (tzinfo is already set)
first plan model causing this error. But when I delete the django_migrations table from DB. error not recurring. it's look like even if I use USE_TZ = True django not inserting date correctly.
My table is defined as below.
class Role(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
to_field="email",
db_column="user",
on_delete=models.CASCADE
)
vertical = models.ForeignKey(
Verticals,
to_field="name",
db_column="vertical",
on_delete=models.CASCADE
)
product_domain = models.ForeignKey(
ProductDomains,
to_field="name",
db_column="product_domain",
null=True,
on_delete=models.CASCADE
)
class Meta:
constraints = [
models.UniqueConstraint(fields=[
'user',
'vertical',
'product_domain'
],
name='unique-permissions-per-user')
]
Here are the migrations that are generated
migrations.CreateModel(
name='Role',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('product_domain', models.ForeignKey(db_column='product_domain', null=True, on_delete=django.db.models.deletion.CASCADE, to='verticals.ProductDomains', to_field='name')),
('user', models.ForeignKey(db_column='user', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, to_field='email')),
('vertical', models.ForeignKey(db_column='vertical', on_delete=django.db.models.deletion.CASCADE, to='verticals.Verticals', to_field='name')),
],
),
migrations.AddConstraint(
model_name='role',
constraint=models.UniqueConstraint(fields=('user', 'vertical', 'product_domain'), name='unique-permissions-per-user'),
),
Serializers for the Role model is
class RoleSerializer(serializers.ModelSerializer):
class Meta:
model = Role
fields = '__all__'
Here is the interactive console for the same
Link to console image (Unable to add due to less reputation )
Here the UniqueConstraint is not working, why?
I use models.UniqueConstraint in the same project many times but it doesn't work in this case.
My configuration is
Django - 3.0.4
Django Rest Framework - 3.11.0
Database - MySql
Please help and ask if any information is missing out.
Your logs don't show any attempt to insert the same record into the DB twice, just validation.
It appears Django Rest Framework does not import constraints from UniqueConstraint, and only has code to validate with the old Meta.unique_together constraint definition.
There is a tracking issue, ModelSerializer not generating validators for constraints, on the DRF GitHub where you can follow the latest updates on adding support for UniqueConstraint validation.
I have a contact information model/form which I want to add a contacttype foreign key to that should be displayed in a drop down menu:
models.py
class ContactType(models.Model):
contact_type = models.CharField(max_length=50)
class Contact(models.Model):
contact_name = models.CharField(max_length=200)
contact_email = models.CharField(max_length=200, validators=[validators.validate_email])
contact_type = models.ForeignKey(ContactType, default='General Enquiry')
forms.py
class ContactForm(forms.ModelForm):
# contact_type = forms.ModelChoiceField(queryset=ContactType.objects.all())
class Meta:
model = Contact
fields = ['contact_name', 'contact_email']
If I leave the contact_type variable where it is, I get the following error:
no such table: contact_contacttype
Here is my last migration:
dependencies = [
('contact', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='ContactType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('contact_type', models.CharField(max_length=50)),
],
),
migrations.AddField(
model_name='contact',
name='contact_type',
field=models.ForeignKey(default='General Enquiry', on_delete=django.db.models.deletion.CASCADE, to='contact.ContactType'),
),
]
whereas if I move it into meta class (should I?) nothing renders into the template.
So my question is, is a foreign key the appropriate relationship? And if so, how should I add the ModelChoiceField to the ContactForm
'authorid' is a foreign key to the Django 'User' model. After running 'makemigrations' and 'migrate' I can not see this field in the sqlite shell.
Here are my models,
class TopicModel(models.Model):
topic = models.CharField(max_length = 100)
topicAuthor = models.CharField(max_length = 100)
authorid = models.ForeignKey(User, related_name = 'id_of_author')
views = models.PositiveIntegerField(default = 0)
def __str__(self):
return self.topic
class PostModel(models.Model):
post = HTMLField(blank = True, max_length = 1000)
pub_date = models.DateTimeField('date published')
author = models.CharField(max_length = 30)
topicid = models.ForeignKey(TopicModel, related_name = 'posts')
def __str__(self):
return self.post
As you can see postmodel also has a foreign key to the topicmodel and there is no problem with this foreign key.
After migration the migrate file 0001_initial.py looks like this,
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import tinymce.models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='PostModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('post', tinymce.models.HTMLField(blank=True, max_length=1000)),
('pub_date', models.DateTimeField(verbose_name='date published')),
('author', models.CharField(max_length=30)),
],
),
migrations.CreateModel(
name='TopicModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('topic', models.CharField(max_length=100)),
('topicAuthor', models.CharField(max_length=100)),
('views', models.PositiveIntegerField(default=0)),
('authorid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='id_of_author', to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='postmodel',
name='topicid',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='posts', to='crudapp.TopicModel'),
),
]
In the sqlite shell the postmodel shows the field with the foreign key, which is topicid_id
sqlite> PRAGMA table_info(crudapp_postmodel);
0|id|integer|1||1
1|pub_date|datetime|1||0
2|author|varchar(30)|1||0
3|topicid_id|integer|1||0
4|post|text|1||0
But when I do the same with the topicmodel, the field with the foreign key doesn't exist, so there is no authorid field.
sqlite> PRAGMA table_info(crudapp_topicmodel);
0|id|integer|1||1
1|topic|varchar(100)|1||0
2|topicAuthor|varchar(100)|1||0
3|views|integer unsigned|1||0
Solution: As suggested by Alasdair I deleted the sqlitedb file and changed the fields from from topicid and authorid to topic and author.
Your current migration should create the foreign keys. My guess is that you updated the migration file after you had already created the crudapp_topicmodel table in the database.
If you don't have any important data yet, the easiest fix is to delete your sqlite file and rerun ./manage.py migrate.
I'm moving the field some_field from Model_A to a new Model_B, with a OneToOne relationship. Before deleting this field in Model_A, I want to copy the value from (the historical) Model_A to the newly created Model_B. The problem is that I cannot retrieve the field at migration time, since Model_A doesn't any longer contain some_field.
This is the error message I get when I try running my custom migration:
AttributeError: 'Model_A' object has no attribute 'some_field'
Models before changes:
class Model_A:
some_field = models.BooleanField(default=False)
some_other_field = models.BooleanField(default=False)
Models after changes:
class Model_A:
some_other_field = models.BooleanField(default=False)
class Model_B:
model_a = models.OneToOneField(Model_A, related_name='extension')
some_field = models.BooleanField(default=False)
Migration:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
def forwards_func(apps, schema_editor):
# This is where I try to get the "historical" Model_A
Model_A = apps2.get_model("my_app", "Model_A")
# And this is where I intend to copy the some_field values
for model_A_instance in Model_A.objects.all():
b = Model_B(model_a=model_A_instance)
# b gets created correctly, but the following step fails
b.some_field = modelA_instance.some_field
b.save()
operations = [
migrations.CreateModel(
name='Model_B',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('some_field', models.BooleanField(default=False)),
('model_a', models.OneToOneField(related_name='extension', to='my_app.Model_A')),
],
options={
},
bases=(models.Model,),
),
migrations.RunPython(forwards_func),
migrations.RemoveField(
model_name='model_a',
name='some_field',
),
]
I'm pretty much aware that I somehow have to get hold of a "historical" representation of Model_A (= the one currently in the database), but I thought that was what the apps2.get_model("my_app", "Model_A") part was for.
Any input on how to accomplish this? Or should I maybe split the migration into two, where the first one creates Model_B + copies the some_field values and the second one deletes the some_field field from Model_A?
Yes, you need to have historical representation of Model_A and it's pretty easy to retrieve it. Thats what apps passed into your function called by RunPython migration is for, so why are you using some apps2 insdead of apps here? Also, you should get your Model_B from same apps instance as Model_A is from. Your migration should look like that:
class Migration(migrations.Migration):
dependencies = [
('my_app', '0001_initial'),
]
def forwards_func(apps, schema_editor):
# This is where I try to get the "historical" Model_A
# here is change - using apps passed into forwards_func by RunPython instead of apps2
Model_A = apps.get_model("my_app", "Model_A")
Model_B = apps.get_model("my_app", "Model_B")
# And this is where I intend to copy the some_field values
for model_A_instance in Model_A.objects.all():
b = Model_B(model_a=model_A_instance)
b.some_field = modelA_instance.some_field
b.save()
operations = [
migrations.CreateModel(
name='Model_B',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('some_field', models.BooleanField(default=False)),
('model_a', models.OneToOneField(related_name='extension', to='my_app.Model_A')),
],
options={
},
bases=(models.Model,),
),
migrations.RunPython(forwards_func),
migrations.RemoveField(
model_name='model_a',
name='some_field',
),
]
Why are you using apps2 anyway? And what it is?