I have decided to implement registration option for my website, I used this tutorial (signup with confirmation part). Following this material I have created Profile module to hold some info. Everything (seems to be) working now, but the problem is that old profiles throws relatedObjectDoesNotExist error. According to these two questions (first, second) I need to make a migration to create profiles for old user accounts. I tried to follow this doc as suggested in one of the answers, but then I try to run a migration I get following error: KeyError: ('stv', 'bazinekaina')
stv is the name of my app and bazinekaina is the name of the next model after the one I need to create profiles.
How to limit migration to only the first model?
My relevant models.py code:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField(max_length=254)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.get(user=instance)
instance.profile.save()
#next model, this one throws an error, despite the fact it should not be touched at all
class BazineKaina(models.Model):
#bazines kainos modelis
bazka = models.DecimalField(max_digits=5, decimal_places=2)
data = models.DateField(auto_now=False, auto_now_add=True)
def __str__(self):
return str(self.bazka)
class Meta:
verbose_name_plural = "Bazinė kaina"
get_latest_by = 'data'
Migration file crated after using python manage.py makemigrations --empty stv command, named 0001_initial.py:
from django.db import migrations, models
def sukurti_profilius(apps, schema_editor):
Profile = apps.get_model("stv", "Profile")
for user in Profile.objects.all():
Profile.objects.get_or_create(user=user)
class Migration(migrations.Migration):
dependencies = [
]
operations = [
]
How and what I should fix to stop migrations from applying to the unrelated models (and throwing error)?
Sorry if it is basic question, but whole django is still very new to me.
If your migration is named 0001_initial then it means that you don't have a migration that actually creates the table for the profile model.
Remove that migration and run:
python manage.py makemigrations stv
python manage.py makemigrations stv --empty --name create_profiles
Then you should have a file 0002_create_profiles.py and put the logic to create profiles there.
Related
I've been building a Django website and included a UUID field "customer_id" in my initial "Customer" model. Finally, I decided to drop it. But when I try to delete it from my models.py, Django throws
SystemCheckError: System check identified some issues:
ERRORS:
<class 'accounts.admin.CustomerAdmin'>: (admin.E035) The value of 'readonly_fields[1]' is not a callable, an attribute of 'CustomerAdmin', or an attribute of 'accounts.Customer'.
Here is the code of models.py
from django.db import models
import uuid
# Create a base model to make sure we keep track of creation and edits
class ModelBaseClass(models.Model):
date_created = models.DateTimeField(auto_now_add=True, null=True)
date_modified = models.DateTimeField(auto_now=True, null=True)
class Meta:
abstract = True
# Create your models here.
class Customer(ModelBaseClass):
customer_id = models.UUIDField(default=uuid.uuid4, #this is the field i try to drop
editable=False,
unique=True)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
What I tried so far:
I suspect that this could be related to existing data or some other dependencies. So...
I deleted the sqlite database, deleted all migration files and ran
"python manage.py makemigrations" and "python manage.py migrate".
I ran python manage.py flush.
I also tried to change the editable=False to editable=True and migrate before dropping,
but it didn't change anything.
It's perhaps also worth mentioning that my "Customer" model a relation to another model.
Could someone explain me why Django is preventing me from deleting this field and how to resolve this?
Thanks! :)
Could someone explain me what's going on and how to resolve this?
As the error says, you have a model admin named CustomerAdmin. Indeed:
<class 'accounts.admin.CustomerAdmin'>: (admin.E035) The value of 'readonly_fields[1]' is not a callable, an attribute of 'CustomerAdmin', or an attribute of 'accounts.Customer'.
For the readonly_fields, it lists the customer_id, but since that field is no longer available, it raises the error.
How fix this? This after when i create new post and when i press button 'add'
It looks like your post is mostly code; please add some more details. Why stackoverflow ask this?
#models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=255)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now= True)
def __str__(self):
return self.title
#admin.py
from django.contrib import admin
from .models import Post
class PostAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',), }
admin.site.register(Post,PostAdmin)
Maybe you forgot to use management commands, makemigrations and migrate after removing status field from your Post model. As far as I can see you don't have status field in your model but this field is still exists in your database. So make sure that field is properly removed from your database by using these management commands (makemigrations and migrate) or if your data is not important you can do the following procedure:
a- Drop your database and create new one
b- Remove all migration files
c- Run manage.py makemigrations and manage.py migrate
I've got this model in my Django application:
class ClubSession(models.Model):
location = models.CharField(max_length=200)
coach = models.ForeignKey('auth.User', on_delete=models.CASCADE)
date = models.DateTimeField(default=now)
details = models.TextField()
def __str__(self):
return self.title
I can run python manage.py makemigrations club_sessions without issue but when I thn run python manage.py migrate club_sessions I get ValueError: Field 'id' expected a number but got 'username'. username is a superuser and already exists.
How do I resolve this?
This is the latest migration:
# Generated by Django 3.0.6 on 2020-05-28 15:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('club_sessions', '0004_auto_20200528_1450'),
]
operations = [
migrations.AlterField(
model_name='clubsession',
name='coach',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='clubsession',
name='location',
field=models.CharField(max_length=200),
),
]
By default Django lets a ForeignKey refer to the primary key of the target model. This also has some advantages to make relations more uniform.
If you really want to save the username in the ForeignKey, you can specify a to_field=… parameter [Django-doc] and let it refer to a column that is unique (the username of the default User model is unique), so we can refer to it with:
from django.conf import settings
class ClubSession(models.Model):
location = models.CharField(max_length=200)
coach = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
to_field='username'
)
date = models.DateTimeField(default=now)
details = models.TextField()
def __str__(self):
return self.title
You will need to remove the already existing migration and make a new one in order to migrate the database properly.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I am new to Django.
IntegrityError: (1364, "Field 'created_at' doesn't have a default value")
occurred when I didn't write created_at for models I defined at models.py.
Every time I face such error, I add
created_at = models.DateTimeField(default=timezone.now, null=True)
to models.py and then run python manage.py makemigrations; python manage.py migrate --fake.
Is that OK? (I mean, does it follow Django best practice or not? )
When I was using Rails, I've never faced such issues. Why doesn't Django automatically handle created_at column?
Also, I'd like to know why --fake option removes this error.
version
Django==1.11.5
mysqlclient==1.3.12
Python 3.6.1
Thanks in advance.
It seems that you want to have an attribute created_at which is set on every creation of a model instance. There is an easier way for that:
created_at = models.DateTimeField(auto_now_add=True)
Here the docs explaining it in detail https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.DateField.auto_now_add
From your comments I think I can reproduce your steps. You had a model class in your models.py:
from django.db import models
class YourModel(models.Model):
one_field = models.CharField()
another_field = models.CharField()
Then you ran:
python manage.py makemigrations
python manage.py migrate
After that you added to your model class:
from django.db import models
class YourModel(models.Model):
one_field = models.CharField()
another_field = models.CharField()
created_at = models.DateTimeField(default=timezone.now, null=True)
but forgot to run the migrations and got the error message.
This is because Django ORM is looking for the property created_at, which it can't find in the DB.
You have to run the commands:
python manage.py makemigrations
python manage.py migrate
again. Remember that the option --fake won't change the DB. It just marks the migration as run. Use it only when you're sure what are you doing.
As Johannes Reichard has suggested you should better use auto_now_add (and there is also auto_now) for this purpose. Check the official documentation.
The drawback is that this field won't be shown in the admin. A workaround is to overwrite the save method:
def save(self, *args, **kwargs):
if not self.pk:
self.created_at = timezone.now() # import it from django.utils
super(YourModel, self).save(*args, **kwargs)
I have a class like this (I didn't know about abstract class at the beginning):
class Client(models.Model):
company_name = models.CharField(max_length=50)
referrer = models.ForeignKey(User, null=True, blank=True)
address = models.CharField(max_length=400, blank=True)
class Customer(Client):
def __str__(self):
return "{company:s}".format(company=self.company_name)
I tried to add abstract class to client, did the makemigrations but migrate crash with this message:
django.core.exceptions.FieldError: Local field 'address' in class 'Customer' clashes with field of similar name from base class 'Client'
I tried to restart from scratch because I don't need migration right now and delete the folder.
I run manage.py migrate and It tells me that I didn't have auth_user table. Then I use manage.py migrate auth then manage.py migrate and it works !
Cool, almost, my django project is now running but when I launch the test I still have the issue:
can't find auth_user table...
I guess test didn't create the migrate auth for the test database.
What did I do wrong?