1

Models.py

    class Bug(models.Model):
        title = models.CharField(max_length=200)
        creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="creator")
        lead = models.ForeignKey(User, default=None, blank=True, null=True, on_delete=models.SET_NULL, 
                                 related_name="lead")
        contributors = models.ManyToManyField(User, default=None, blank=True, null=True, 
                                              related_name="contributors")
        project = models.ForeignKey(Project, null=True, on_delete=models.CASCADE)
        created_at = models.DateTimeField(default=timezone.now)
        last_modified = models.DateTimeField(auto_now=True)
        status = models.ForeignKey(Status, on_delete=models.CASCADE, default=0)
        description = models.TextField()
    
        class Meta:
            constraints = [
                models.CheckConstraint(
                    check=(
                        models.Q(
                            abs(datetime.now().microsecond - created_at.microsecond) > 10
                        )
                    ),
                    name="%(app_label)s_%(class)s_exact_date",
                )
            ]

When I attempt to run tests on it I get the following error: NameError: name 'created_at' is not defined

I am trying to enforce a constraint that the created_at date for a bug be either exactly the time it was created or within some tight bound of the time that it was created. I wish to enforce it at the database level because I'm trying to secure the data not only from form entry (in which case I could just add a validator or add editable=false on the field), but also from any other attempt to save incorrect data to the database through the ORM. I'm also using constraints rather than validators because I don't want to have to override multiple functions (save(), update(), etc).

System information: Python v3.9.0, Django v3.1.4

Shyrtle
  • 647
  • 5
  • 20
  • Is there existing data in this model? If so, was any data added before adding the created_at field? You could try adding an if statement, in case your created_at doesn't exist. Something like `if created_at:` then do what you need to in meta, and put an `else` for what you would want it to do if there is not a created_at. – Shyrtle Feb 04 '21 at 00:28
  • 1
    Why not just use the built-in `auto_now_add=True` attribute on your DateTimeField? `models.DateTimeField(auto_now_add=True)` – Foot Feb 04 '21 at 04:20
  • @Shyrtle, There are existing data in the model. (The database is using Postgresql). I checked over the data and I don't see any entries with a missing `created_at`. I will try using an if statement and respond to that part of the question. Would there be any other reason that the reference is out of scope though? I'm confused because I was basing it exactly off of code I've seen online, but that code seems to have worked and mine doesn't. – Dallas Hoekstra Feb 05 '21 at 16:16
  • @Foot, That looks exactly like what I am trying to do: I hadn't used it because I wasn't aware of it. :) I've only been working with Django for about a month, so there are still a lot of new features I'm running across. I'd still like an answer to my original question because I'd like to know how to properly write constraints for future reference. – Dallas Hoekstra Feb 05 '21 at 16:21
  • I can post an answer that shows how to create a constraint on `created_at`. But if your constraint is basically `created_at must be more than 10 microseconds older than Now()`, it would likely be violated on any "normal" insert (i.e. by the ORM) unless you're setting `created_at` to something in the past manually (which is not recommended). Can you state in simple terms what the issue is you want to avoid re: the Bug's creation time? – Foot Feb 08 '21 at 17:51
  • @Foot, I would appreciate an aswer which explains why the particular code is causing an error/not defined because I don't understand what I'm doing wrong with the construction of a general constraint. I think the effect of the code would actually be `created_at must be 10 microseconds older or newer than Now()` since is used abs(), but yes. I was anticipating it causing errors with the ORM for any number of reasons (my thought was that it might take longer that 10 microseconds). Essentially: The constraint should ensure the date is the time of creation and cannot be altered. (see prev resp) – Dallas Hoekstra Feb 09 '21 at 18:34

0 Answers0