1. Constraint in class CertificateInvalidation
generated_certificate
should be unique in the model CertificateInvalidation
, as one certificate should not be invalidated twice. This would cause exceptions in the program which hurts the data integrity. We can add unique=True
to prevent that.
In file lms/djangoapps/certificates/models.py
class CertificateInvalidation(TimeStampedModel):
"""
Model for storing Certificate Invalidation.
.. no_pii:
"""
generated_certificate = models.ForeignKey(GeneratedCertificate, on_delete=models.CASCADE)
invalidated_by = models.ForeignKey(User, on_delete=models.CASCADE)
2. Constraint in class BadgeAssertion
Each user should only have one completion badge. We can add this data constraint with
unique_together=('user', 'badge_class')
to avoid invalid data to get in the database.
# Usage in lms/djangoapps/badges/events/course_complete.py
if BadgeAssertion.objects.filter(user=user, badge_class=badge_class):
LOGGER.info("Completion badge already exists for this user on this course.")
# definition in lms/djangoapps/badges/models.py
class BadgeAssertion(TimeStampedModel):
"""
Tracks badges on our side of the badge baking transaction
.. no_pii:
"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
badge_class = models.ForeignKey(BadgeClass, on_delete=models.CASCADE)
3. Constraint in class LoginFailures
Similar issue, user field should be unique for the LoginFailures, this would prevent duplicate entries for the same user, due to potential race conditions of get_or_create()
in the first place.
class LoginFailures(models.Model):
"""
This model will keep track of failed login attempts.
.. no_pii:
"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
failure_count = models.IntegerField(default=0)
lockout_until = models.DateTimeField(null=True)
I can work on the PR for this issue if needed, please let me know your thoughts. Thanks!