diff --git a/base-requirements.txt b/base-requirements.txt
index 2495153db..06e1990e4 100644
--- a/base-requirements.txt
+++ b/base-requirements.txt
@@ -13,10 +13,10 @@ psycopg2-binary==2.8.6
python3-openid==3.2.0
python-decouple==3.4
# lxml used by BeautifulSoup.
-lxml==4.6.3
+lxml==4.9.2
cssselect==1.1.0
feedparser==6.0.8
-beautifulsoup4==4.9.3
+beautifulsoup4==4.11.2
icalendar==4.0.7
chardet==4.0.0
# TODO: We may drop 'django-imagekit' completely.
diff --git a/blogs/tests/test_views.py b/blogs/tests/test_views.py
index ee7df723b..5c6c5053f 100644
--- a/blogs/tests/test_views.py
+++ b/blogs/tests/test_views.py
@@ -27,12 +27,3 @@ def test_blog_home(self):
latest = BlogEntry.objects.latest()
self.assertEqual(resp.context['latest_entry'], latest)
-
- def test_blog_redirects(self):
- """
- Test that when '/blog/' is hit, it redirects '/blogs/'
- """
- response = self.client.get('/blog/')
- self.assertRedirects(response,
- '/blogs/',
- status_code=301)
diff --git a/config/nginx.conf.erb b/config/nginx.conf.erb
index 527fdc0df..42bbf94cc 100644
--- a/config/nginx.conf.erb
+++ b/config/nginx.conf.erb
@@ -84,6 +84,10 @@ http {
return 301 https://www.python.org/psf;
}
+ location ~ ^/community-landing/?(.*)$ {
+ return 301 https://www.python.org/community/;
+ }
+
location /doc/Summary {
return 301 http://legacy.python.org/doc/intros/summary;
}
@@ -204,6 +208,22 @@ http {
return 301 https://www.python.org/download/windows/;
}
+ location /download/ {
+ return 301 https://www.python.org/downloads/;
+ }
+
+ location /download/source/ {
+ return 301 https://www.python.org/downloads/source/;
+ }
+
+ location /download/mac/ {
+ return 301 https://www.python.org/downloads/macos/;
+ }
+
+ location /download/windows/ {
+ return 301 https://www.python.org/downloads/windows/;
+ }
+
location /Mirrors.html {
return 301 https://www.python.org/mirrors/;
}
@@ -292,6 +312,10 @@ http {
return 302 /blogs/;
}
+ location /blog/ {
+ return 301 https://python.org/blogs/;
+ }
+
location /static/ {
alias /app/static-root/;
add_header Cache-Control "max-age=604800, public"; # 604800 is 7 days
diff --git a/downloads/api.py b/downloads/api.py
index e58023dbf..73eb9b7bf 100644
--- a/downloads/api.py
+++ b/downloads/api.py
@@ -69,7 +69,7 @@ class Meta(GenericResource.Meta):
'creator', 'last_modified_by',
'os', 'release', 'description', 'is_source', 'url', 'gpg_signature_file',
'md5_sum', 'filesize', 'download_button', 'sigstore_signature_file',
- 'sigstore_cert_file', 'sigstore_bundle_file',
+ 'sigstore_cert_file', 'sigstore_bundle_file', 'sbom_spdx2_file',
]
filtering = {
'name': ('exact',),
diff --git a/downloads/migrations/0010_releasefile_sbom_spdx2_file.py b/downloads/migrations/0010_releasefile_sbom_spdx2_file.py
new file mode 100644
index 000000000..f3a4784e9
--- /dev/null
+++ b/downloads/migrations/0010_releasefile_sbom_spdx2_file.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.24 on 2024-01-12 21:04
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('downloads', '0009_releasefile_sigstore_bundle_file'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='releasefile',
+ name='sbom_spdx2_file',
+ field=models.URLField(blank=True, help_text='SPDX-2 SBOM URL', verbose_name='SPDX-2 SBOM URL'),
+ ),
+ ]
diff --git a/downloads/models.py b/downloads/models.py
index 6d91534ac..4a9c5781c 100644
--- a/downloads/models.py
+++ b/downloads/models.py
@@ -332,6 +332,9 @@ class ReleaseFile(ContentManageable, NameSlugModel):
sigstore_bundle_file = models.URLField(
"Sigstore Bundle URL", blank=True, help_text="Sigstore Bundle URL"
)
+ sbom_spdx2_file = models.URLField(
+ "SPDX-2 SBOM URL", blank=True, help_text="SPDX-2 SBOM URL"
+ )
md5_sum = models.CharField('MD5 Sum', max_length=200, blank=True)
filesize = models.IntegerField(default=0)
download_button = models.BooleanField(default=False, help_text="Use for the supernav download button for this OS")
diff --git a/downloads/serializers.py b/downloads/serializers.py
index 67bde5b5c..1ff57049f 100644
--- a/downloads/serializers.py
+++ b/downloads/serializers.py
@@ -49,4 +49,5 @@ class Meta:
'sigstore_signature_file',
'sigstore_cert_file',
'sigstore_bundle_file',
+ 'sbom_spdx2_file',
)
diff --git a/downloads/templatetags/download_tags.py b/downloads/templatetags/download_tags.py
index fb3496787..c72f6d58c 100644
--- a/downloads/templatetags/download_tags.py
+++ b/downloads/templatetags/download_tags.py
@@ -14,3 +14,42 @@ def has_sigstore_materials(files):
f.sigstore_bundle_file or f.sigstore_cert_file or f.sigstore_signature_file
for f in files
)
+
+
+@register.filter
+def has_sbom(files):
+ return any(f.sbom_spdx2_file for f in files)
+
+
+@register.filter
+def sort_windows(files):
+ if not files:
+ return files
+
+ # Put Windows files in preferred order
+ files = list(files)
+ windows_files = []
+ other_files = []
+ for preferred in (
+ 'Windows installer (64-bit)',
+ 'Windows installer (32-bit)',
+ 'Windows installer (ARM64)',
+ 'Windows help file',
+ 'Windows embeddable package (64-bit)',
+ 'Windows embeddable package (32-bit)',
+ 'Windows embeddable package (ARM64)',
+ ):
+ for file in files:
+ if file.name == preferred:
+ windows_files.append(file)
+ files.remove(file)
+ break
+
+ # Then append any remaining Windows files
+ for file in files:
+ if file.name.startswith('Windows'):
+ windows_files.append(file)
+ else:
+ other_files.append(file)
+
+ return other_files + windows_files
diff --git a/downloads/tests/base.py b/downloads/tests/base.py
index e19ffe03a..bcb7905c4 100644
--- a/downloads/tests/base.py
+++ b/downloads/tests/base.py
@@ -64,6 +64,7 @@ def setUp(self):
is_source=True,
description='Gzipped source',
url='ftp/python/2.7.5/Python-2.7.5.tgz',
+ filesize=12345678,
)
self.draft_release = Release.objects.create(
diff --git a/downloads/tests/test_views.py b/downloads/tests/test_views.py
index 75fe76693..50270c556 100644
--- a/downloads/tests/test_views.py
+++ b/downloads/tests/test_views.py
@@ -40,6 +40,9 @@ def test_download_release_detail(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
+ with self.subTest("Release file sizes should be human-readable"):
+ self.assertInHTML("
11.8 MB ", response.content.decode())
+
url = reverse('download:download_release_detail', kwargs={'release_slug': 'fake_slug'})
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
diff --git a/fixtures/boxes.json b/fixtures/boxes.json
index b0e965011..bc3816cc7 100644
--- a/fixtures/boxes.json
+++ b/fixtures/boxes.json
@@ -174,9 +174,9 @@
"created": "2013-10-28T19:27:20.963Z",
"updated": "2022-01-05T15:42:59.645Z",
"label": "widget-use-python-for",
- "content": "\r\nMore
\r\n\r\n",
+ "content": "\r\nMore
\r\n\r\n",
"content_markup_type": "html",
- "_content_rendered": "\r\nMore
\r\n\r\n"
+ "_content_rendered": "\r\nMore
\r\n\r\n"
}
},
{
diff --git a/pydotorg/urls.py b/pydotorg/urls.py
index 5fc6b3f12..c112b2e19 100644
--- a/pydotorg/urls.py
+++ b/pydotorg/urls.py
@@ -3,7 +3,7 @@
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
from django.urls import path, re_path
-from django.views.generic.base import TemplateView, RedirectView
+from django.views.generic.base import TemplateView
from django.conf import settings
from cms.views import custom_404
@@ -24,18 +24,11 @@
# python section landing pages
path('about/', TemplateView.as_view(template_name="python/about.html"), name='about'),
- # Redirect old download links to new downloads pages
- path('download/', RedirectView.as_view(url='https://www.python.org/downloads/', permanent=True)),
- path('download/source/', RedirectView.as_view(url='https://www.python.org/downloads/source/', permanent=True)),
- path('download/mac/', RedirectView.as_view(url='https://www.python.org/downloads/macos/', permanent=True)),
- path('download/windows/', RedirectView.as_view(url='https://www.python.org/downloads/windows/', permanent=True)),
-
# duplicated downloads to getit to bypass China's firewall. See
# https://github.com/python/pythondotorg/issues/427 for more info.
path('getit/', include('downloads.urls', namespace='getit')),
path('downloads/', include('downloads.urls', namespace='download')),
path('doc/', views.DocumentationIndexView.as_view(), name='documentation'),
- path('blog/', RedirectView.as_view(url='/blogs/', permanent=True)),
path('blogs/', include('blogs.urls')),
path('inner/', TemplateView.as_view(template_name="python/inner.html"), name='inner'),
diff --git a/sponsors/admin.py b/sponsors/admin.py
index d6601140f..88aff8c57 100644
--- a/sponsors/admin.py
+++ b/sponsors/admin.py
@@ -246,9 +246,13 @@ def has_delete_permission(self, request, obj=None):
return True
return obj.open_for_editing
- def get_queryset(self, *args, **kwargs):
- qs = super().get_queryset(*args, **kwargs)
- return qs.select_related("sponsorship_benefit__program", "program")
+ def get_queryset(self, request):
+ #filters the available benefits by the benefits for the year of the sponsorship
+ match = request.resolver_match
+ sponsorship = self.parent_model.objects.get(pk=match.kwargs["object_id"])
+ year = sponsorship.year
+
+ return super().get_queryset(request).filter(sponsorship_benefit__year=year)
class TargetableEmailBenefitsFilter(admin.SimpleListFilter):
diff --git a/sponsors/forms.py b/sponsors/forms.py
index 5a31605af..4ced017c9 100644
--- a/sponsors/forms.py
+++ b/sponsors/forms.py
@@ -221,6 +221,11 @@ class SponsorshipApplicationForm(forms.Form):
help_text="For promotion of your sponsorship on social media.",
required=False,
)
+ linked_in_page_url = forms.URLField(
+ label="LinkedIn page URL",
+ help_text="URL for your LinkedIn page.",
+ required=False,
+ )
web_logo = forms.ImageField(
label="Sponsor web logo",
help_text="For display on our sponsor webpage. High resolution PNG or JPG, smallest dimension no less than 256px",
@@ -253,10 +258,17 @@ class SponsorshipApplicationForm(forms.Form):
state = forms.CharField(
label="State/Province/Region", max_length=64, required=False
)
+ state_of_incorporation = forms.CharField(
+ label="State of incorporation", help_text="US only, If different than mailing address", max_length=64, required=False
+ )
postal_code = forms.CharField(
label="Zip/Postal Code", max_length=64, required=False
)
- country = CountryField().formfield(required=False)
+ country = CountryField().formfield(required=False, help_text="For mailing/contact purposes")
+
+ country_of_incorporation = CountryField().formfield(
+ label="Country of incorporation", help_text="For contractual purposes", required=False
+ )
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user", None)
@@ -372,7 +384,10 @@ def save(self):
description=self.cleaned_data.get("description", ""),
landing_page_url=self.cleaned_data.get("landing_page_url", ""),
twitter_handle=self.cleaned_data["twitter_handle"],
+ linked_in_page_url=self.cleaned_data["linked_in_page_url"],
print_logo=self.cleaned_data.get("print_logo"),
+ country_of_incorporation=self.cleaned_data.get("country_of_incorporation", ""),
+ state_of_incorporation=self.cleaned_data.get("state_of_incorporation", ""),
)
contacts = [f.save(commit=False) for f in self.contacts_formset.forms]
for contact in contacts:
diff --git a/sponsors/management/commands/create_pycon_vouchers_for_sponsors.py b/sponsors/management/commands/create_pycon_vouchers_for_sponsors.py
index f8b99855a..3e3b4973d 100644
--- a/sponsors/management/commands/create_pycon_vouchers_for_sponsors.py
+++ b/sponsors/management/commands/create_pycon_vouchers_for_sponsors.py
@@ -20,22 +20,26 @@
)
BENEFITS = {
- 121: {
- "internal_name": "full_conference_passes_2023_code",
+ 183: {
+ "internal_name": "full_conference_passes_code_2024",
"voucher_type": "SPNS_COMP_",
},
- 139: {
- "internal_name": "expo_hall_only_passes_2023_code",
+ 201: {
+ "internal_name": "expo_hall_only_passes_code_2024",
"voucher_type": "SPNS_EXPO_COMP_",
},
- 148: {
- "internal_name": "additional_full_conference_passes_2023_code",
+ 208: {
+ "internal_name": "additional_full_conference_passes_code_2024",
"voucher_type": "SPNS_ADDL_DISC_REG_",
},
- 166: {
- "internal_name": "online_only_conference_passes_2023_code",
+ 225: {
+ "internal_name": "online_only_conference_passes_2024",
"voucher_type": "SPNS_ONLINE_COMP_",
},
+ 237: {
+ "internal_name": "additional_expo_hall_only_passes_2024",
+ "voucher_type": "SPNS_EXPO_DISC_",
+ },
}
diff --git a/sponsors/migrations/0100_auto_20240107_1054.py b/sponsors/migrations/0100_auto_20240107_1054.py
new file mode 100644
index 000000000..8bad2bc92
--- /dev/null
+++ b/sponsors/migrations/0100_auto_20240107_1054.py
@@ -0,0 +1,29 @@
+# Generated by Django 2.2.24 on 2024-01-07 10:54
+
+from django.db import migrations, models
+import django_countries.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sponsors', '0099_auto_20231224_1854'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='sponsor',
+ name='country_of_incorporation',
+ field=django_countries.fields.CountryField(blank=True, help_text='For contractual purposes', max_length=2, null=True, verbose_name='Country of incorporation (If different)'),
+ ),
+ migrations.AddField(
+ model_name='sponsor',
+ name='state_of_incorporation',
+ field=models.CharField(blank=True, default='', max_length=64, null=True, verbose_name='US only: State of incorporation (If different)'),
+ ),
+ migrations.AlterField(
+ model_name='sponsor',
+ name='country',
+ field=django_countries.fields.CountryField(default='', help_text='For mailing/contact purposes', max_length=2),
+ ),
+ ]
diff --git a/sponsors/migrations/0101_sponsor_linked_in_page_url.py b/sponsors/migrations/0101_sponsor_linked_in_page_url.py
new file mode 100644
index 000000000..61041a08e
--- /dev/null
+++ b/sponsors/migrations/0101_sponsor_linked_in_page_url.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.24 on 2024-02-09 13:30
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sponsors', '0100_auto_20240107_1054'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='sponsor',
+ name='linked_in_page_url',
+ field=models.URLField(blank=True, help_text='URL for your LinkedIn page.', null=True, verbose_name='LinkedIn page URL'),
+ ),
+ ]
diff --git a/sponsors/models/sponsors.py b/sponsors/models/sponsors.py
index eee7f585e..78d5d6e32 100644
--- a/sponsors/models/sponsors.py
+++ b/sponsors/models/sponsors.py
@@ -44,6 +44,12 @@ class Sponsor(ContentManageable):
null=True,
verbose_name="Twitter handle",
)
+ linked_in_page_url = models.URLField(
+ blank=True,
+ null=True,
+ verbose_name="LinkedIn page URL",
+ help_text="URL for your LinkedIn page."
+ )
web_logo = models.ImageField(
upload_to="sponsor_web_logos",
verbose_name="Web logo",
@@ -73,8 +79,15 @@ class Sponsor(ContentManageable):
postal_code = models.CharField(
verbose_name="Zip/Postal Code", max_length=64, default=""
)
- country = CountryField(default="")
+ country = CountryField(default="", help_text="For mailing/contact purposes")
assets = GenericRelation(GenericAsset)
+ country_of_incorporation = CountryField(
+ verbose_name="Country of incorporation (If different)", help_text="For contractual purposes", blank=True, null=True
+ )
+ state_of_incorporation = models.CharField(
+ verbose_name="US only: State of incorporation (If different)",
+ max_length=64, blank=True, null=True, default=""
+ )
class Meta:
verbose_name = "sponsor"
diff --git a/sponsors/tests/test_forms.py b/sponsors/tests/test_forms.py
index 123dc1729..49b0515cd 100644
--- a/sponsors/tests/test_forms.py
+++ b/sponsors/tests/test_forms.py
@@ -423,14 +423,18 @@ def test_create_sponsor_with_valid_data(self):
def test_create_sponsor_with_valid_data_for_non_required_inputs(
self,
):
+ user = baker.make(settings.AUTH_USER_MODEL)
+
self.data["description"] = "Important company"
self.data["landing_page_url"] = "https://companyx.com"
self.data["twitter_handle"] = "@companyx"
+ self.data["country_of_incorporation"] = "US"
+ self.data["state_of_incorporation"] = "NY"
self.files["print_logo"] = get_static_image_file_as_upload(
"psf-logo_print.png", "logo_print.png"
)
- form = SponsorshipApplicationForm(self.data, self.files)
+ form = SponsorshipApplicationForm(self.data, self.files, user=user)
self.assertTrue(form.is_valid(), form.errors)
sponsor = form.save()
@@ -440,6 +444,8 @@ def test_create_sponsor_with_valid_data_for_non_required_inputs(
self.assertFalse(form.user_with_previous_sponsors)
self.assertEqual(sponsor.landing_page_url, "https://companyx.com")
self.assertEqual(sponsor.twitter_handle, "@companyx")
+ self.assertEqual(sponsor.country_of_incorporation, "US")
+ self.assertEqual(sponsor.state_of_incorporation, "NY")
def test_create_sponsor_with_svg_for_print_logo(
self,
diff --git a/static/sass/style.css b/static/sass/style.css
index c3d2bb5f9..a58863817 100644
--- a/static/sass/style.css
+++ b/static/sass/style.css
@@ -3405,6 +3405,23 @@ span.highlighted {
.icon-megaphone span, .icon-python-alt span, .icon-pypi span, .icon-news span, .icon-moderate span, .icon-mercurial span, .icon-jobs span, .icon-help span, .icon-download span, .icon-documentation span, .icon-community span, .icon-code span, .icon-close span, .icon-calendar span, .icon-beginner span, .icon-advanced span, .icon-sitemap span, .icon-search span, .icon-search-alt span, .icon-python span, .icon-github span, .icon-get-started span, .icon-feed span, .icon-facebook span, .icon-email span, .icon-arrow-up span, .icon-arrow-right span, .icon-arrow-left span, .icon-arrow-down span, .errorlist:before span, .icon-freenode span, .icon-alert span, .icon-versions span, .icon-twitter span, .icon-thumbs-up span, .icon-thumbs-down span, .icon-text-resize span, .icon-success-stories span, .icon-statistics span, .icon-stack-overflow span, .icon-mastodon span {
display: none; }
+.fa {
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ margin-right: .5em;
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ /* Hide a unicode fallback character when we supply it by default.
+ * In fonts.scss, we hide the icon and show the fallback when other conditions are not met
+ */ }
+ .fa {
+ display: none; }
+
/* Keep this at the bottom since it will create a huge set of data */
/*
* Would have liked to use Compass' built-in font-face mixin with the inline-font-files() helper, but it seems to be BROKEN in older versions!
diff --git a/static/sass/style.scss b/static/sass/style.scss
index 2e0ea8981..4fd9a3efd 100644
--- a/static/sass/style.scss
+++ b/static/sass/style.scss
@@ -2426,6 +2426,24 @@ span.highlighted {
*/
span { display: none; }
}
+.fa {
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ margin-right: .5em;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ /* Hide a unicode fallback character when we supply it by default.
+ * In fonts.scss, we hide the icon and show the fallback when other conditions are not met
+ */
+ span { display: none; }
+}
/* Keep this at the bottom since it will create a huge set of data */
@import "fonts";
diff --git a/templates/base.html b/templates/base.html
index 27daceb50..424df06f6 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -41,6 +41,7 @@
{% stylesheet 'style' %}
{% stylesheet 'mq' %}
+ {% stylesheet 'font-awesome' %}
{% comment %}
{# equivalent to: #}
@@ -235,10 +236,10 @@
Socialize
diff --git a/templates/downloads/os_list.html b/templates/downloads/os_list.html
index 67db5233f..1e0177dca 100644
--- a/templates/downloads/os_list.html
+++ b/templates/downloads/os_list.html
@@ -1,6 +1,7 @@
{% extends "downloads/base.html" %}
{% load boxes %}
{% load sitetree %}
+{% load sort_windows from download_tags %}
{% block body_attributes %}class="python download"{% endblock %}
@@ -45,7 +46,7 @@ Stable Releases
{% endif %}
{% endif %}
- {% for f in r.files.all %}
+ {% for f in r.files.all|sort_windows %}
Download {{ f.name }}
{% empty %}
No files for this release.
@@ -63,7 +64,7 @@ Pre-releases
{{ r.name }} - {{ r.release_date|date }}
- {% for f in r.files.all %}
+ {% for f in r.files.all|sort_windows %}
Download {{ f.name }}
{% empty %}
No files for this release.
diff --git a/templates/downloads/release_detail.html b/templates/downloads/release_detail.html
index b68b69a66..720887074 100644
--- a/templates/downloads/release_detail.html
+++ b/templates/downloads/release_detail.html
@@ -2,6 +2,8 @@
{% load boxes %}
{% load sitetree %}
{% load has_sigstore_materials from download_tags %}
+{% load has_sbom from download_tags %}
+{% load sort_windows from download_tags %}
{% block body_attributes %}class="python downloads"{% endblock %}
@@ -53,16 +55,19 @@ Files
{% if release_files|has_sigstore_materials %}
Sigstore
{% endif %}
+ {% if release_files|has_sbom %}
+ SBOM
+ {% endif %}
- {% for f in release_files %}
+ {% for f in release_files|sort_windows %}
{{ f.name }}
{{ f.os.name }}
{{ f.description }}
{{ f.md5_sum }}
- {{ f.filesize }}
+ {{ f.filesize|filesizeformat }}
{% if f.gpg_signature_file %}SIG {% endif %}
{% if release_files|has_sigstore_materials %}
{% if f.sigstore_bundle_file %}
@@ -72,6 +77,9 @@ Files
{% if f.sigstore_signature_file %}SIG {% endif %}
{% endif %}
{% endif %}
+ {% if release_files|has_sbom %}
+ {% if f.sbom_spdx2_file %}SPDX {% endif %}
+ {% endif %}
{% endfor %}
diff --git a/templates/jobs/job_detail.html b/templates/jobs/job_detail.html
index 82ddd3f58..be073e551 100644
--- a/templates/jobs/job_detail.html
+++ b/templates/jobs/job_detail.html
@@ -8,7 +8,7 @@
{% block content_attributes %}with-right-sidebar{% endblock %}
{% block og_title %}Job: {{ object.job_title }} at {{ object.company_name }}{% endblock %}
-{% block og-descript %}{{ object.description|truncatechars:200 }}{% endblock %}
+{% block og-descript %}{{ object.description|escape|truncatechars:200 }}{% endblock %}
{% block content %}
{% load companies %}
diff --git a/templates/sponsors/new_sponsorship_application_form.html b/templates/sponsors/new_sponsorship_application_form.html
index 9f7597650..c95bdf4ea 100644
--- a/templates/sponsors/new_sponsorship_application_form.html
+++ b/templates/sponsors/new_sponsorship_application_form.html
@@ -2,15 +2,19 @@
{% load boxes widget_tweaks %}
{% load humanize %}
{% load sponsors %}
+{% block page_title %}Sponsorship Information{% endblock %}
-{% block page_title %}Submit Sponsorship Information{% endblock %}
{% block content %}
{% endblock content %}
diff --git a/templates/users/sponsor_info_update.html b/templates/users/sponsor_info_update.html
index 3ae2e720c..1312fb782 100644
--- a/templates/users/sponsor_info_update.html
+++ b/templates/users/sponsor_info_update.html
@@ -17,6 +17,7 @@
{% block user_content %}
-
+
+
+ {{ form.linked_in_page_url.label }} {% if form.linked_in_page_url.errors %}
+ {{ form.linked_in_page_url.errors.as_text }} {% endif %}
+ {% render_field form.linked_in_page_url%}
+ {% if form.linked_in_page_url.help_text %}
+
+ {{ form.linked_in_page_url.help_text }}
+ {% endif %}
+
+
+
+
+
{{ form.country.label }} {% if form.country.errors %}
{{ form.country.errors.as_text }} {% endif %}
{% render_field form.country %}
{% if form.country.help_text %}
-
{{ form.country.help_text }}
{% endif %}
+
+
+
+ {{ form.country_of_incorporation.label }} {% if form.country_of_incorporation.errors %}
+ {{ form.country.errors.as_text }} {% endif %}
+ {% render_field form.country_of_incorporation %}
+ {% if form.country_of_incorporation.help_text %}
+
+ {{ form.country_of_incorporation.help_text }}
+ {% endif %}
+
+
+
@@ -131,8 +181,19 @@
Sponsor Information
{{ form.state.help_text }}
{% endif %}
+
+
+
+ {{ form.state_of_incorporation.label }} {% if form.state_of_incorporation.errors %}
+ {{ form.state_of_incorporation.errors.as_text }} {% endif %}
+ {% render_field form.state %}
+ {% if form.state_of_incorporation.help_text %}
+
+ {{ form.state_of_incorporation.help_text }}
+ {% endif %}
+
+
-
diff --git a/users/tests/test_views.py b/users/tests/test_views.py
index 952425c98..13c226e5f 100644
--- a/users/tests/test_views.py
+++ b/users/tests/test_views.py
@@ -489,7 +489,7 @@ def test_display_template_with_sponsor_info(self):
response = self.client.get(self.url)
context = response.context
- self.assertTemplateUsed(response, "users/sponsor_info_update.html")
+ self.assertTemplateUsed(response, "sponsors/new_sponsorship_application_form.html")
self.assertEqual(context["sponsor"], self.sponsor)
self.assertIsInstance(context["form"], SponsorUpdateForm)
diff --git a/users/views.py b/users/views.py
index 517c1419a..c56dbace4 100644
--- a/users/views.py
+++ b/users/views.py
@@ -264,7 +264,7 @@ def get_context_data(self, *args, **kwargs):
@method_decorator(login_required(login_url=settings.LOGIN_URL), name="dispatch")
class UpdateSponsorInfoView(UpdateView):
object_name = "sponsor"
- template_name = 'users/sponsor_info_update.html'
+ template_name = 'sponsors/new_sponsorship_application_form.html'
form_class = SponsorUpdateForm
def get_queryset(self):