Création de table dans la base de données
bonjour à tous !
Sans le faire exprès, j'ai effacé la tables ShippingAddress et tout le contenu de mon fichier models.py. À l'intérieur du models.py, j'avais mon modèle Shopper et ma classe ShippingAddress.
J'ai réécrit le code à nouveau, mais je rencontre une KeyError lors de la migration pour recréer les tables
fields = self.models[model_key].fields
KeyError: ('accounts', 'shippingaddress')
class CustomUserManager(BaseUserManager):
def create_user(self, email, password, **kwargs):
if not email:
raise ValueError(" email is required")
email = self.normalize_email(email)
# on recupere notre model Shopper
user = self.model(email=email, **kwargs)
# on cripte le password
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **kwargs):
# on set les valeur sur notre dictionnaire
kwargs["is_staff"] = True
kwargs["is_superuser"] = True
kwargs["is_active"] = True
# on passe la dictionnaire a la fonction create_user
return self.create_user(email=email, password=password, **kwargs)
class Shopper(AbstractUser):
username = None
email = models.EmailField(max_length=240, unique=True)
USERNAME_FIELD = "email"
# d'autres champs requis en + de email
REQUIRED_FIELDS = []
objects = CustomUserManager()
class Shippingaddress(models.Model):
# user peut avoir plusieurs address
user = models.ForeignKey(Shopper, on_delete=models.CASCADE)
name = models.CharField(max_length=240)
address_1 = models.CharField(max_length=1024, help_text="numéro de rue adresse de voirie")
address_2 = models.CharField(max_length=1024, help_text="bâtiment, etage... ", blank=True)
city = models.CharField(max_length=1024)
zip_code = models.CharField(max_length=32)
country = models.CharField(max_length=2, choices=[(c.alpha2.lower(), c.name) for c in countries])

bonjour Thibault,
non je ne pense pas avoir fais cela mais les migrations doivent nous en apprendre davantage j'imagine.
voici le dossier de migration de l'application accounts :

class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='Shopper',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
]
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='shopper',
name='stripe_id',
field=models.CharField(blank=True, max_length=90),
),
migrations.AlterField(
model_name='shippingaddress',
name='address_1',
field=models.CharField(help_text='adresse de voirie et numéro de rue', max_length=1024),
),
]
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_shopper_stripe_id_alter_shippingaddress_address_1'),
]
operations = [
migrations.AddField(
model_name='shippingaddress',
name='phone',
field=phone_field.models.PhoneField(blank=True, help_text='numéro de téléphone', max_length=31),
),
]
salut pa !
oui j'ai déjà inséré des enregistrements dans chaque table de la base de données.
Salut Konimba !
Alors déboguer des problèmes de migration à distance c'est toujours compliqué, il y a beaucoup de choses qui peuvent faire que ça plante et on peut y passer longtemps (si tu as supprimé juste certains éléments dans ta base de données, ou seulement d'autres dans les modèles ou les migrations, il faut vraiment faire du debug assez poussé).
Ce que je te propose c'est de repartir de 0 avec ta base de données et tes migrations car vu qu'il s'agit du projet de formation j'imagine que tu n'as pas de données ultra importantes à conserver dans ta BDD.
Du coup tu peux suivre ces étapes pour repartir sur une "clean slate" :
1) Supprime tous les fichiers dans ton dossier de migration, sauf __init__.py.
2) Ensuite, ouvre ton shell Django et supprime aussi les tables de ta base de données. Tu peux faire ça avec la commande python manage.py shell suivie de :
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("DROP TABLE IF EXISTS nom_de_ta_table_1")
cursor.execute("DROP TABLE IF EXISTS nom_de_ta_table_2")
# continue comme ça pour chaque table que tu as.
Remplace
nom_de_ta_table_1 par le nom de tes différentes tables.
Tu peux le faire aussi directement depuis le shell Postgres (psql) avec les mêmes commandes si tu préfères ou depuis une interface graphique comme TablePlus que tu sembles utiliser si je tiens compte de tes screenshots :)
3) Ensuite, sors de ton shell Django et fais un python manage.py makemigrations. Ça va recreer les fichiers de migration.
4) Et enfin, fais un python manage.py migrate pour recréer tes tables dans la base de données.
Tiens nous au courant !
Merci à vous tous,
Ça fonctionne parfaitement.
Je pense que dans les projets un peu plus avancés, comme celui-ci,
il aurait été plus prudent de ma part d'utiliser Git afin d'éviter ce genre de désagrément.
Peut-être que dans de nouveaux projets, vous pourriez l'inclure pour créer l'habitude et éviter ce type d'intervention.
Merci encore
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte