Django test : Field 'id' expected a number but got datetime.datetime

Viewed 44

It's my first time doing tests in a Django app, and I don't understand my error. When i run python manage.py test, I got this error :

D:\Users\boucardale\Documents\code\djangotest>python manage.py test

You are in dev mode
Found 1 test(s).
Creating test database for alias 'default'...
Traceback (most recent call last):
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1988, in get_prep_value
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'datetime.datetime'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\commands\test.py", line 24, in run_from_argv
    super().run_from_argv(argv)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\base.py", line 414, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\base.py", line 460, in execute
    output = self.handle(*args, **options)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\commands\test.py", line 68, in handle
    failures = test_runner.run_tests(test_labels)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\test\runner.py", line 1000, in run_tests
    old_config = self.setup_databases(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\test\runner.py", line 898, in setup_databases
    return _setup_databases(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\test\utils.py", line 220, in setup_databases
    connection.creation.create_test_db(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\backends\base\creation.py", line 79, in create_test_db
    call_command(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\__init__.py", line 198, in call_command
    return command.execute(*args, **defaults)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\base.py", line 460, in execute
    output = self.handle(*args, **options)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\base.py", line 98, in wrapped
    res = handle_func(*args, **kwargs)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\core\management\commands\migrate.py", line 290, in handle
    post_migrate_state = executor.migrate(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\migrations\executor.py", line 131, in migrate
    state = self._migrate_all_forwards(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\migrations\executor.py", line 163, in _migrate_all_forwards
    state = self.apply_migration(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\migrations\executor.py", line 248, in apply_migration
    state = migration.apply(state, schema_editor)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\migrations\migration.py", line 131, in apply
    operation.database_forwards(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\migrations\operations\fields.py", line 108, in database_forwards
    schema_editor.add_field(
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 381, in add_field
    self._remake_table(model, create_field=field)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 230, in _remake_table
    self.effective_default(create_field)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\backends\base\schema.py", line 410, in effective_default
    return field.get_db_prep_save(self._effective_default(field), self.connection)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\models\fields\related.py", line 1126, in get_db_prep_save
    return self.target_field.get_db_prep_save(value, connection=connection)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\models\fields\__init__.py", line 910, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\models\fields\__init__.py", line 2668, in get_db_prep_value
    value = self.get_prep_value(value)
  File "D:\Users\boucardale\Documents\code\djangotest\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1990, in get_prep_value
    raise e.__class__(
TypeError: Field 'id' expected a number but got datetime.datetime(2022, 9, 16, 9, 7, 36, 977154).

Here is my test file:

from django.urls import reverse
import datetime
from django.test import TestCase
from django.core.management import call_command


from comptes.models import User
from projects.models import Project


class ProjectTest(TestCase):

    def setUp(self):
        call_command("init_config")

        self.admin_user = User.objects.create(email="admin_user@fabdev.fr", username="admin_user")
        self.admin_user.set_password('123456TEST')
        self.admin_user.save()

        self.standard_user = User.objects.create(email="standard_user@fabdev.fr", username="standard_user")
        self.standard_user.set_password('123456TEST')
        self.standard_user.save()


    def test_ProjectCreate(self):
        """
        Test qui vérifie la création d'un nouveau projet
        """
        field = ['operations', 'state', 'name', 'eotp', 'creation_date', 'eotp_validation_date', 'analysis_date',
                 'end_date', 'entity', 'synthese', 'aoi', 'price', 'estimated_price', 'decision', 'decision_in_explorer',
                 'description', 'commentary', 'decision_level', 'decision_sheet', 'qualification', 'decision_number',
                 'decision_number_link', 'code_site', 'applicant', 'immobilisation_family_a', 'immobilisation_family_b',
                 'immobilisation_family_c', 'immobilisation_family_d', 'immobilisation_family_e', 'immobilisation_family_f',
                 'immobilisation_family_g', 'immobilisation_family_h', 'archived', 'last_editor', 'last_modification_date',
                 'related_projects', 'old_project_pk', 'copy', 'responsible', 'auto_created']
        excpected = [None, 'Nouvelle décision - à traiter', 'test_project', 'TESTEOTP',
                     datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                     datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                     datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                     datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                     'GMR Dauphiné', None, None, 5, 5, 'decision', 'decision_in_explorer', 'description', 'commentary',
                     'Immobilisations', 'decision_sheet', 'CAPEX', 'decision_number', 'decision_number_link', 'SITEE',
                     'demandeur', True, True, False, False, False, True, False, False, False,
                     User.objects.get(username='standard_user'), datetime.datetime.now(), None, None, False,
                     User.objects.get(username='standard_user'), False]
        self.client.login(username='standard_user', password='123456TEST')
        url = reverse('project-create')

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        response = self.client.post(url, {'state': 'Nouvelle décision - à traiter',
                                          'name': 'test_project',
                                          'eotp': 'TESTEOTP',
                                          'creation_date': datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                                          'eopt_validation_date': datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                                          'analysis_date': datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                                          'end_date': datetime.datetime.strptime("15/09/2022", "%d/%m/%y"),
                                          'entity': 'GMR Dauphiné',
                                          'synthese': None,
                                          'aoi': None,
                                          'price': 5,
                                          'estimated_price': 5,
                                          'decision': 'decision',
                                          'decision_in_explorer': 'decision_in_explorer',
                                          'description': 'description',
                                          'commentary': 'commentary',
                                          'decision_level': 'Immobilisations',
                                          'decision_sheet': 'decision_sheet',
                                          'qualification': 'CAPEX',
                                          'decision_number': 'decision_number',
                                          'decision_number_link': 'decision_number_link',
                                          'code_site': 'SITEE',
                                          'applicant': 'demandeur',
                                          'immobilisation_family_a': True,
                                          'immobilisation_family_b': True,
                                          'immobilisation_family_c': False,
                                          'immobilisation_family_d': False,
                                          'immobilisation_family_e': False,
                                          'immobilisation_family_f': True,
                                          'immobilisation_family_g': False,
                                          'immobilisation_family_h': False,
                                          'responsible': User.objects.get(username='standard_user')})
        project = Project.objects.get(name='test_project')
        for i in range(len(excpected)):
            self.assertEqual(project[field[i]], excpected[i])

Does anyone know why I have this error ? Does it come from my settings ? Thanks for your help

[EDIT]

I add my 'Project' Model and my 'project-create' view :

STATES = (
    ('#FFFFFF', 'Présenté par la DI avant ZSM37'),
    ('#FFFF00', 'Nouvelle décision - à traiter'),
    ('#FFFF99', 'Décision arrivée dans la ZSM37 mais non analysée le jour même'),
    ('#FF0000', 'Non validé => demande de renseignements pour statuer'),
    ('#FFFFFE', "NON Validé le jour de la création de l'EOTP mais Validé ultérieurement"),
    ('#00CC00', "Validé le jour de la création de l'EOTP"),
    ('#66B2FF', 'Non validé => opération à supprimer'),
    ('#0080FF', 'Non validé => opération supprimée'),
)

QUALIFICATION = (
    ('CAPEX', 'CAPEX'),
    ('OPEX/CAPEX', 'OPEX/CAPEX'),
    ('OPEX', 'OPEX'),
)

ENTITIES = (
    ("SC Saint Denis et CNES", "SC Saint Denis et CNES"),
    ("SC et Ctre Explt Lille", "SC et Ctre Explt Lille"),
    ("GMR Dauphiné", "GMR Dauphiné"),
)

class Project(models.Model):
    DECISION_LEVEL = (                  # les différents niveaux de décision que peut avoir un projet
        ('Immobilisations', 'Immobilisations'),
        ('Immobilisations + Synthèse', 'Immobilisations + Synthèse'),
        ('Comité de décision', 'Comité de décision'),
        ('ZSM vers Qualif', 'ZSM vers Qualif'),
        ('RRR vers Qualif', 'RRR vers Qualif'),
    )

    operations = models.ManyToManyField(Operation, related_name="project_operations")
    state = models.CharField(max_length=7, choices=STATES, verbose_name="Statut", default="Nouvelle décision - à traiter")
    name = models.CharField(max_length=200, verbose_name="Nom du projet", default="")
    eotp = models.CharField(max_length=100, verbose_name="EOTP", blank=True, null=True, unique=True)
    creation_date = models.DateField(verbose_name="Date de création du projet")
    eotp_validation_date = models.DateField(verbose_name="Date de validation de l'EOTP", blank=True, null=True)
    analysis_date = models.DateField(verbose_name="Date d'analyse", blank=True, null=True)
    end_date = models.DateField(verbose_name="Date de fin du projet", blank=True, null=True)
    entity = models.CharField(max_length=200, choices=ENTITIES, verbose_name="Entité/Sous-Entité", blank=True, null=True)
    synthese = models.ManyToManyField(SyntheseUser, verbose_name="Suivi à synthèse", related_name="synthese_project")
    aoi = models.ManyToManyField(AOIUser, verbose_name="Suivi à AOI", related_name="aoi_project")
    price = models.FloatField(verbose_name="Montant (en K€)", default=0)
    estimated_price = models.FloatField(verbose_name="Montant prévisionnel (en K€)", default=0)
    decision = models.TextField(verbose_name="Décision", blank=True, null=True)
    decision_in_explorer = models.TextField(verbose_name="Lien vers ECPR", blank=True, null=True)
    description = models.TextField(verbose_name="Description du projet", blank=True, null=True)
    commentary = models.TextField(verbose_name="Commentaire (situation/avis)", blank=True, null=True)
    decision_level = models.CharField(max_length=26, choices=DECISION_LEVEL, verbose_name="Niveau de décision",
                                      default='Immobilisations')
    decision_sheet = models.TextField(verbose_name="Lien vers la fiche de décision", blank=True, null=True)
    qualification = models.CharField(max_length=10, choices=QUALIFICATION, verbose_name="Qualification comptable",
                                     default="Non défini")
    decision_number = models.CharField(verbose_name="Numéro de décision", max_length=50, blank=True, null=True, unique=True)
    decision_number_link = models.TextField(verbose_name="Lien vers le numéro de décision", blank=True, null=True)
    code_site = models.CharField(max_length=5, verbose_name="Code site", blank=True, null=True)
    applicant = models.CharField(max_length=200, verbose_name="Demandeur(s)", blank=True, null=True)
    immobilisation_family_a = models.BooleanField(default=False, verbose_name="A")
    immobilisation_family_b = models.BooleanField(default=False, verbose_name="\tB")
    immobilisation_family_c = models.BooleanField(default=False, verbose_name="\tC")
    immobilisation_family_d = models.BooleanField(default=False, verbose_name="\tD")
    immobilisation_family_e = models.BooleanField(default=False, verbose_name="\tE")
    immobilisation_family_f = models.BooleanField(default=False, verbose_name="\tF")
    immobilisation_family_g = models.BooleanField(default=False, verbose_name="\tG")
    immobilisation_family_h = models.BooleanField(default=False, verbose_name="\tH")
    archived = models.BooleanField(default=False, verbose_name="Archiver le projet")
    last_editor = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, verbose_name="Dernier modificateur", related_name="last_editor")
    last_modification_date = models.DateTimeField(blank=True, null=True, verbose_name="Date de modification")
    related_projects = models.ManyToManyField('self', blank=True)
    old_project_pk = models.IntegerField(blank=True, null=True)
    copy = models.BooleanField(default=False)
    responsible = models.ForeignKey(User, null=True, on_delete=models.SET_NULL,
                                    verbose_name="Interlocuteur", related_name="project_responsible")
    auto_created = models.BooleanField(default="False", verbose_name="Créé automatiquement")

    def __str__(self):
        return self.name

    def get_operations(self):
        return ", ".join([str(o) for o in self.operations.all()])

    def get_related_projects(self):
        return ", ".join([str(o) for o in self.related_projects.all()])

    def get_aoi_users(self):
        if self.aoi.all().count() == 0:
            return "[vide]"
        return ", ".join([str(a) for a in self.aoi.all()])

    def get_synthese_users(self):
        if self.synthese.all().count() == 0:
            return "[vide]"
        return ", ".join([str(s) for s in self.synthese.all()])
class ProjectForm(forms.ModelForm):             # formulaire pour les projets (création ou modification)
    class Meta:
        model = Project
        fields = ['state', 'name', 'eotp', 'creation_date', 'eotp_validation_date', 'analysis_date',
                  'end_date', 'entity', 'synthese', 'aoi', 'price', 'estimated_price', 'decision',
                  'decision_in_explorer', 'description', 'commentary', 'decision_level',
                  'decision_sheet', 'qualification', 'decision_number', 'decision_number_link', 'code_site',
                  'applicant', 'immobilisation_family_a', 'immobilisation_family_b',
                  'immobilisation_family_c', 'immobilisation_family_d', 'immobilisation_family_e',
                  'immobilisation_family_f', 'immobilisation_family_g', 'immobilisation_family_h', 'responsible']

    synthese = forms.ModelMultipleChoiceField(
        queryset=SyntheseUser.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        required=False, label="Suivi à Synthèse")

    aoi = forms.ModelMultipleChoiceField(
        queryset=AOIUser.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        required=False, label="Suivi à AOI")

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(ProjectForm, self).__init__(*args, **kwargs)
        self.initial['eotp'] = get_initial_eotp(self.request.path)
        if self.request.path == "/creation/":
            self.initial['responsible'] = self.request.user


class ProjectCreate(LoginRequiredMixin, SuccessMessageMixin, CreateView):  # formulaire de création de projet
    model = Project
    form_class = ProjectForm
    success_url = reverse_lazy("project-list")
    success_message = "Nouveau projet créé"

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update({'request': self.request})
        return kwargs

    def get_form(self, form_class=None):
        form = super(ProjectCreate, self).get_form(form_class)
        form.fields['creation_date'].widget = AdminDateWidget(attrs={'type': 'date'})
        form.fields['eotp_validation_date'].widget = AdminDateWidget(attrs={'type': 'date'})
        form.fields['analysis_date'].widget = AdminDateWidget(attrs={'type': 'date'})
        form.fields['end_date'].widget = AdminDateWidget(attrs={'type': 'date'})
        return form

    def form_valid(self, form):
        form.instance.decision_sheet = add_https(form.instance.decision_sheet)
        form.instance.last_editor = self.request.user
        form.instance.last_modification_date = datetime.datetime.now()
        form.instance.save()
        if self.request.POST.get('related_projects'):
            form.instance.related_projects.add(get_project_from_eotp(self.request.POST.get('related_projects')))
            form.instance.save()
        return super().form_valid(form)

    def get_success_url(self):
        url = self.request.GET.get('next')
        if url:
            return url
        return reverse_lazy("project-list")
0 Answers
Related