Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1379 certifications checklist #14

Open
wants to merge 27 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c77e25c
extract zipfile inside zipfile in sample data lesson
sumandari May 17, 2021
d09aeb5
update unit test for download sample data lesson
sumandari May 17, 2021
0092fff
update unit test
sumandari May 17, 2021
7de9b96
fixed dockerfile for development and the documentation
Nov 23, 2021
547869c
fixed raising ValidationError in validate_email_address
sumandari Nov 26, 2021
79e0987
fixed typo flake8
sumandari Nov 26, 2021
bfab4ac
Merge pull request #1374 from sumandari/fix_dev_docker_and_readme
Nov 26, 2021
f4b45d3
Merge branch 'develop' of https://github.com/kartoza/prj.app into 137…
sumandari Nov 26, 2021
7f837e5
Merge pull request #1376 from sumandari/1372_fix_update_sustaining_me…
Dec 2, 2021
c1a2cb5
Merge pull request #1341 from sumandari/1328_lesson_extract_zip_in_zi…
Dec 2, 2021
613dbe7
added CertificateType model
sumandari Dec 3, 2021
a1c5b72
added admin class
sumandari Dec 3, 2021
3fb6b64
added CertificateType as foreign key in Certificate models and update…
sumandari Dec 3, 2021
af6b582
updated unittest
sumandari Dec 3, 2021
ec6763c
added project certificate_type
sumandari Dec 10, 2021
1f76a37
part#2: enable certification manager to manage certificate type list
sumandari Dec 10, 2021
935b99a
fixed typo flake8
sumandari Dec 11, 2021
45ca0e3
Part#3: added certificate_type in courseform
sumandari Dec 11, 2021
5c798d9
removed certificate_type in certificate model
sumandari Dec 11, 2021
22db5b5
updated queryset in courseform
sumandari Dec 16, 2021
2adf94e
Part#4 update template
sumandari Dec 16, 2021
5aeacd6
fixed typo flake8
sumandari Dec 16, 2021
85bd0b4
updated unit test and fix failed test
sumandari Dec 24, 2021
cf89c41
updated unit test and fix failed test
sumandari Dec 24, 2021
2cfa122
checklist app add and move order
sumandari Jan 17, 2022
32fce95
archive-activate checklist
sumandari Jan 20, 2022
db63d6e
remove unused files
sumandari Jan 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ When it's done, you can continue with this command:
Linux and MacOS:

```
cp docker-compose.override.example.yml docker-compose.override.yml
make build-devweb
make devweb
cp docker-compose.override.example.yml docker-compose.override.yml
```

In case you don't get some not installed packages, you can run this
Expand All @@ -54,6 +54,7 @@ repeatable steps:
Windows:

```
copy docker-compose.override.example.yml docker-compose.override.yml
make-devbuild.bat
make-devweb.bat
```
Expand Down
6 changes: 3 additions & 3 deletions deployment/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ MAINTAINER Tim Sutton<[email protected]>
#RUN ln -s /bin/true /sbin/initctl

# Pandoc needed to generate rst dumps, uic compressor needed for django-pipeline
RUN apt-get update -y; apt-get -y --force-yes install yui-compressor gettext
RUN apt-get update -y && apt-get -y --force-yes install yui-compressor gettext
RUN wget https://github.com/jgm/pandoc/releases/download/1.17.1/pandoc-1.17.1-2-amd64.deb
RUN dpkg -i pandoc-1.17.1-2-amd64.deb && rm pandoc-1.17.1-2-amd64.deb

Expand All @@ -18,7 +18,7 @@ ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1
ADD deployment/docker/REQUIREMENTS.txt /REQUIREMENTS.txt
ADD deployment/docker/uwsgi.conf /uwsgi.conf
ADD django_project /home/web/django_project
RUN pip install -r /REQUIREMENTS.txt
RUN pip install --upgrade pip && pip install -r /REQUIREMENTS.txt
RUN pip install uwsgi


Expand Down Expand Up @@ -50,7 +50,7 @@ RUN echo "export VISIBLE=now" >> /etc/profile
# End of cut & paste section

ADD deployment/docker/REQUIREMENTS-dev.txt /REQUIREMENTS-dev.txt
RUN pip install -r /REQUIREMENTS-dev.txt
RUN pip install --upgrade pip && pip install -r /REQUIREMENTS-dev.txt
ADD deployment/docker/bashrc /root/.bashrc

# --------------------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions django_project/certification/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.contrib.gis import admin
from simple_history.admin import SimpleHistoryAdmin
from certification.models.certificate import Certificate
from certification.models.certificate_type import CertificateType
from certification.models.course import Course
from certification.models.training_center import TrainingCenter
from certification.models.course_convener import CourseConvener
Expand Down Expand Up @@ -34,6 +35,15 @@ def queryset(self, request):
return query_set


class CertificateTypeAdmin(admin.ModelAdmin):
"""CertificateType admin model."""

list_display = ('name', 'wording', 'order')
list_editable = ('order', )
search_fields = ('name', 'wording')
ordering = ('order', )


class AttendeeAdmin(admin.ModelAdmin):
"""Attendee admin model."""
list_display = ('firstname', 'surname', 'email', 'certifying_organisation')
Expand Down Expand Up @@ -163,6 +173,7 @@ class StatusAdmin(admin.ModelAdmin):


admin.site.register(Certificate, CertificateAdmin)
admin.site.register(CertificateType, CertificateTypeAdmin)
admin.site.register(Attendee, AttendeeAdmin)
admin.site.register(Course, CourseAdmin)
admin.site.register(CourseType, CourseTypeAdmin)
Expand Down
Empty file.
7 changes: 7 additions & 0 deletions django_project/certification/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
)
from .models import (
CertifyingOrganisation,
CertificateType,
CourseConvener,
CourseType,
TrainingCenter,
Expand Down Expand Up @@ -303,6 +304,7 @@ class Meta:
'end_date',
'template_certificate',
'certifying_organisation',
'certificate_type',
)

def __init__(self, *args, **kwargs):
Expand All @@ -322,6 +324,7 @@ def __init__(self, *args, **kwargs):
Field('start_date', css_class='form-control'),
Field('end_date', css_class='form-control'),
Field('template_certificate', css_class='form-control'),
Field('certificate_type', css_class='form-control'),
)
)
self.helper.layout = layout
Expand All @@ -342,6 +345,10 @@ def __init__(self, *args, **kwargs):
self.certifying_organisation
self.fields['certifying_organisation'].widget = forms.HiddenInput()
self.helper.add_input(Submit('submit', 'Submit'))
self.fields['certificate_type'].queryset = \
CertificateType.objects.filter(
projectcertificatetype__project=
self.certifying_organisation.project)

def save(self, commit=True):
instance = super(CourseForm, self).save(commit=False)
Expand Down
34 changes: 34 additions & 0 deletions django_project/certification/migrations/0007_certificatetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 2.2.18 on 2021-12-03 00:56

from django.db import migrations, models


def add_certification_type_as_existing_value(apps, schema_editor):
CertificateType = apps.get_model('certification', 'CertificateType')
CertificateType.objects.create(
name='attendance and completion',
wording='Has attended and completed the course:',
order=0
)


class Migration(migrations.Migration):

dependencies = [
('certification', '0006_auto_20210730_0615'),
]

operations = [
migrations.CreateModel(
name='CertificateType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='Certificate type.', max_length=200, unique=True)),
('description', models.TextField(blank=True, help_text='Certificate type description - 1000 characters limit.', max_length=1000, null=True)),
('wording', models.CharField(help_text='Wording that will be placed on certificate. e.g. "Has attended and completed".', max_length=500)),
('order', models.IntegerField(blank=True, null=True, unique=True)),
],
),

migrations.RunPython(add_certification_type_as_existing_value, reverse_code=migrations.RunPython.noop),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 2.2.18 on 2021-12-10 02:23

from django.db import migrations, models
import django.db.models.deletion

def create_existing_project_certificate_type(apps, schema_editor):
CertificateType = apps.get_model('certification', 'CertificateType')
ProjectCertificateType = apps.get_model('certification', 'ProjectCertificateType')
Project = apps.get_model('base', 'Project')
certificate_type = CertificateType.objects.filter(
name='attendance and completion').first()
projects = Project.objects.all()

for project in projects:
ProjectCertificateType.objects.create(
project=project,
certificate_type=certificate_type
)

class Migration(migrations.Migration):

dependencies = [
('base', '0006_auto_20210308_0244'),
('certification', '0007_certificatetype'),
]

operations = [
migrations.CreateModel(
name='ProjectCertificateType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('certificate_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='certification.CertificateType')),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.Project')),
],
),

migrations.RunPython(create_existing_project_certificate_type, reverse_code=migrations.RunPython.noop),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 2.2.18 on 2021-12-10 08:31

from django.db import migrations, models
import django.db.models.deletion

def set_existing_certificate_type_value(apps, shcema_editor):
CertificateType = apps.get_model('certification', 'CertificateType')
Course = apps.get_model('certification', 'Course')
certificate_type = CertificateType.objects.filter(
name='attendance and completion').first()
courses = Course.objects.all()

for course in courses:
course.certificate_type = certificate_type
course.save(update_fields=['certificate_type'])


class Migration(migrations.Migration):

dependencies = [
('certification', '0008_projectcertificatetype'),
]

operations = [
migrations.AddField(
model_name='course',
name='certificate_type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='certification.CertificateType'),
),

migrations.RunPython(set_existing_certificate_type_value, reverse_code=migrations.RunPython.noop),

migrations.AlterField(
model_name='course',
name='certificate_type',
field=models.ForeignKey(null=False, on_delete=django.db.models.deletion.PROTECT,
to='certification.CertificateType'),
preserve_default=False,
),

]
33 changes: 33 additions & 0 deletions django_project/certification/migrations/0010_auto_20220115_1805.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 2.2.18 on 2022-01-15 16:05

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('base', '0006_auto_20210308_0244'),
('certification', '0009_course_certificate_type'),
]

operations = [
migrations.AlterField(
model_name='course',
name='certificate_type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='certification.CertificateType'),
),
migrations.CreateModel(
name='CertificateChecklist',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('question', models.CharField(help_text='Question for certifying organisation applicant.', max_length=1000, unique=True)),
('sort_number', models.SmallIntegerField(blank=True, help_text='The order in which this category is listed within a project', null=True)),
('is_archived', models.BooleanField(default=False, help_text='Is this question archived?')),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.Project')),
],
options={
'unique_together': {('question', 'sort_number')},
},
),
]
1 change: 1 addition & 0 deletions django_project/certification/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
from certification.models.course_attendee import *
from certification.models.course_type import *
from certification.models.course_convener import *
from certification.models.certificate_type import *
from certification.models.certificate import *
from certification.models.organisation_certificate import *
32 changes: 32 additions & 0 deletions django_project/certification/models/certificate_checklist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Certificate application model for certification apps."""

from django.db import models
from django.utils.translation import ugettext_lazy as _


class CertificateChecklist(models.Model):
question = models.CharField(
help_text=_('Question for certifying organisation applicant.'),
max_length=1000,
unique=True,
)
Comment on lines +8 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
question = models.CharField(
help_text=_('Question for certifying organisation applicant.'),
max_length=1000,
unique=True,
)
question = models.TextField(
help_text=_('Question for certifying organisation applicant.'), unique=True
)

TextField might be better used here, instead of CharField with a huge max_length. More.

Comment on lines +8 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
question = models.CharField(
help_text=_('Question for certifying organisation applicant.'),
max_length=1000,
unique=True,
)
question = models.TextField(
help_text=_('Question for certifying organisation applicant.'), unique=True
)

TextField might be better used here, instead of CharField with a huge max_length. More.

Comment on lines +8 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
question = models.CharField(
help_text=_('Question for certifying organisation applicant.'),
max_length=1000,
unique=True,
)
question = models.TextField(
help_text=_('Question for certifying organisation applicant.'), unique=True
)

TextField might be better used here, instead of CharField with a huge max_length. Read more.

Comment on lines +8 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
question = models.CharField(
help_text=_('Question for certifying organisation applicant.'),
max_length=1000,
unique=True,
)
question = models.TextField(
help_text=_('Question for certifying organisation applicant.'), unique=True
)

TextField might be better used here, instead of CharField with a huge max_length. More info.

Comment on lines +8 to +12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
question = models.CharField(
help_text=_('Question for certifying organisation applicant.'),
max_length=1000,
unique=True,
)
question = models.TextField(
help_text=_('Question for certifying organisation applicant.'), unique=True
)

TextField might be better used here, instead of CharField with a huge max_length. More details.

sort_number = models.SmallIntegerField(
help_text=_(
'The order in which this category is listed within a '
'project'),
blank=True,
null=True
)
is_archived = models.BooleanField(
help_text=_('Is this question archived?'),
default=False
)
project = models.ForeignKey('base.Project', on_delete=models.CASCADE)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. Explained here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. Read more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. Explained here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More info.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. Read more.


class Meta:
unique_together = (
('question', 'sort_number'),
)

def __str__(self):
return f'[{self.project.name}] {self.question}'
55 changes: 55 additions & 0 deletions django_project/certification/models/certificate_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Certificate type model for certification app"""

from django.db import models
from django.utils.translation import ugettext_lazy as _

from base.models.project import Project


class CertificateType(models.Model):
name = models.CharField(
help_text=_('Certificate type.'),
max_length=200,
null=False,
blank=False,
unique=True,
)
Comment on lines +10 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = models.CharField(
help_text=_('Certificate type.'),
max_length=200,
null=False,
blank=False,
unique=True,
)
name = models.CharField(help_text=_("Certificate type."), max_length=200, unique=True)

False is the default value Django uses for null, so null=False can be removed. More info.

Similarly, redundant default arguments can be removed.

Comment on lines +10 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = models.CharField(
help_text=_('Certificate type.'),
max_length=200,
null=False,
blank=False,
unique=True,
)
name = models.CharField(help_text=_("Certificate type."), max_length=200, unique=True)

False is the default value Django uses for null, so null=False can be removed. Explained here.

As above, redundant default arguments can be removed.

Comment on lines +10 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = models.CharField(
help_text=_('Certificate type.'),
max_length=200,
null=False,
blank=False,
unique=True,
)
name = models.CharField(help_text=_("Certificate type."), max_length=200, unique=True)

False is the default value Django uses for null, so null=False can be removed. More info.

Again, redundant default arguments can be removed.

Comment on lines +10 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = models.CharField(
help_text=_('Certificate type.'),
max_length=200,
null=False,
blank=False,
unique=True,
)
name = models.CharField(help_text=_("Certificate type."), max_length=200, unique=True)

False is the default value Django uses for null, so null=False can be removed. More.

Again, redundant default arguments can be removed.

Comment on lines +10 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = models.CharField(
help_text=_('Certificate type.'),
max_length=200,
null=False,
blank=False,
unique=True,
)
name = models.CharField(help_text=_("Certificate type."), max_length=200, unique=True)

False is the default value Django uses for null, so null=False can be removed. Read more.

As above, redundant default arguments can be removed.


description = models.TextField(
help_text=_('Certificate type description - 1000 characters limit.'),
max_length=1000,
null=True,
blank=True,
)
Comment on lines +18 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description = models.TextField(
help_text=_('Certificate type description - 1000 characters limit.'),
max_length=1000,
null=True,
blank=True,
)
description = models.TextField(
help_text=_("Certificate type description - 1000 characters limit."),
max_length=1000,
default="",
blank=True,
)

null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Explained here.

Comment on lines +18 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description = models.TextField(
help_text=_('Certificate type description - 1000 characters limit.'),
max_length=1000,
null=True,
blank=True,
)
description = models.TextField(
help_text=_("Certificate type description - 1000 characters limit."),
max_length=1000,
default="",
blank=True,
)

null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Explained here.

Comment on lines +18 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description = models.TextField(
help_text=_('Certificate type description - 1000 characters limit.'),
max_length=1000,
null=True,
blank=True,
)
description = models.TextField(
help_text=_("Certificate type description - 1000 characters limit."),
max_length=1000,
default="",
blank=True,
)

null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". More info.

Comment on lines +18 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description = models.TextField(
help_text=_('Certificate type description - 1000 characters limit.'),
max_length=1000,
null=True,
blank=True,
)
description = models.TextField(
help_text=_("Certificate type description - 1000 characters limit."),
max_length=1000,
default="",
blank=True,
)

null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Explained here.

Comment on lines +18 to +23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description = models.TextField(
help_text=_('Certificate type description - 1000 characters limit.'),
max_length=1000,
null=True,
blank=True,
)
description = models.TextField(
help_text=_("Certificate type description - 1000 characters limit."),
max_length=1000,
default="",
blank=True,
)

null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Explained here.


wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. '
'e.g. "Has attended and completed".'
),
max_length=500,
null=False,
blank=False
)
Comment on lines +25 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. '
'e.g. "Has attended and completed".'
),
max_length=500,
null=False,
blank=False
)
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. e.g. "Has attended and completed".'
),
max_length=500,
)

Same as above: redundant default arguments can be removed.

Again, redundant default arguments can be removed.

Comment on lines +25 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. '
'e.g. "Has attended and completed".'
),
max_length=500,
null=False,
blank=False
)
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. e.g. "Has attended and completed".'
),
max_length=500,
)

As above, redundant default arguments can be removed.

Similarly, redundant default arguments can be removed.

Comment on lines +25 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. '
'e.g. "Has attended and completed".'
),
max_length=500,
null=False,
blank=False
)
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. e.g. "Has attended and completed".'
),
max_length=500,
)

Likewise, redundant default arguments can be removed.

Similarly, redundant default arguments can be removed.

Comment on lines +25 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. '
'e.g. "Has attended and completed".'
),
max_length=500,
null=False,
blank=False
)
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. e.g. "Has attended and completed".'
),
max_length=500,
)

As above, redundant default arguments can be removed.

Again, redundant default arguments can be removed.

Comment on lines +25 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. '
'e.g. "Has attended and completed".'
),
max_length=500,
null=False,
blank=False
)
wording = models.CharField(
help_text=_(
'Wording that will be placed on certificate. e.g. "Has attended and completed".'
),
max_length=500,
)

Likewise, redundant default arguments can be removed.

As above, redundant default arguments can be removed.


order = models.IntegerField(
blank=True,
null=True,
unique=True
)

def __str__(self):
return self.name


class ProjectCertificateType(models.Model):
"""A model to store a certificate type linked to a project"""

project = models.ForeignKey(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More info.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More info.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. Explained here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More details.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. Explained here.

Project,
on_delete=models.CASCADE
)
certificate_type = models.ForeignKey(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, with an explicit related_name would be better.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, with an explicit related_name would be better.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, with an explicit related_name would be better.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: with an explicit related_name would be better.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: with an explicit related_name would be better.

CertificateType,
on_delete=models.CASCADE
)
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ def validate_email_address(value):
try:
validate_email(value)
return True
except ValidationError(
except ValidationError:
raise ValidationError(
_('%(value)s is not a valid email address'),
params={'value': value},):
return False
params={'value': value},
)


class CertifyingOrganisation(models.Model):
Expand Down
3 changes: 3 additions & 0 deletions django_project/certification/models/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .course_type import CourseType
from certification.utilities import check_slug
from .training_center import TrainingCenter
from certification.models.certificate_type import CertificateType

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -86,6 +87,8 @@ class Course(models.Model):
on_delete=models.CASCADE)
certifying_organisation = models.ForeignKey(CertifyingOrganisation,
on_delete=models.CASCADE)
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True)
Comment on lines +90 to +91

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True)
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True, blank=True
)

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More details.

Expect unwanted behavior if null and blank are different values: null controls if the database allows no value for certificate_type and blank controls if the application allows no value for certificate_type. Consider setting null and blank to the same value for certificate_type. More details.

Comment on lines +90 to +91

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True)
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True, blank=True
)

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More details.

Expect unwanted behavior if null and blank are different values: null controls if the database allows no value for certificate_type and blank controls if the application allows no value for certificate_type. Consider setting null and blank to the same value for certificate_type. More details.

Comment on lines +90 to +91

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True)
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True, blank=True
)

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More info.

Expect unwanted behavior if null and blank are different values: null controls if the database allows no value for certificate_type and blank controls if the application allows no value for certificate_type. Consider setting null and blank to the same value for certificate_type. Read more.

Comment on lines +90 to +91

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True)
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True, blank=True
)

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More info.

Expect unwanted behavior if null and blank are different values: null controls if the database allows no value for certificate_type and blank controls if the application allows no value for certificate_type. Consider setting null and blank to the same value for certificate_type. More info.

Comment on lines +90 to +91

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True)
certificate_type = models.ForeignKey(
CertificateType, on_delete=models.PROTECT, null=True, blank=True
)

Django automatically creates a related_name if it's not set. If it were set then a more readable and explicit relationship is set up. More info.

Expect unwanted behavior if null and blank are different values: null controls if the database allows no value for certificate_type and blank controls if the application allows no value for certificate_type. Consider setting null and blank to the same value for certificate_type. More info.

author = models.ForeignKey(User, on_delete=models.CASCADE)
objects = models.Manager()

Expand Down
Loading