mirror of
https://github.com/kristoferssolo/FOSSDB.git
synced 2025-10-21 17:50:35 +00:00
Some changes
This commit is contained in:
parent
9019c76d5a
commit
6759ff4b58
2
.gitignore
vendored
2
.gitignore
vendored
@ -135,3 +135,5 @@ debug
|
||||
/static/admin/
|
||||
/static/fontawesomefree/
|
||||
config.json
|
||||
/media/profile_pics/*
|
||||
!/media/profile_pics/default.jpg
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 12:54
|
||||
# Generated by Django 4.2.2 on 2023-06-27 16:35
|
||||
|
||||
import account.models
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
@ -17,7 +18,7 @@ class Migration(migrations.Migration):
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CustomUser',
|
||||
name='User',
|
||||
fields=[
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
@ -30,6 +31,7 @@ class Migration(migrations.Migration):
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('profile_picture', models.ImageField(default='profile_pics/default.jpg', upload_to=account.models.get_profile_pic_path)),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
||||
],
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:02
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='customuser',
|
||||
name='profile_pic',
|
||||
field=models.ImageField(default='default.jpg', upload_to='profile_pics/'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0002_customuser_profile_pic'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='profile_pic',
|
||||
field=models.BinaryField(blank=True),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0003_alter_customuser_profile_pic'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='profile_pic',
|
||||
field=models.BinaryField(blank=True, editable=True),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:33
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0004_alter_customuser_profile_pic'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='customuser',
|
||||
old_name='profile_pic',
|
||||
new_name='profile_picture',
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0005_rename_profile_pic_customuser_profile_picture'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='profile_picture',
|
||||
field=models.ImageField(default='profile_pic/default.jpg', upload_to='profile_pics/'),
|
||||
),
|
||||
]
|
||||
@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:43
|
||||
|
||||
import account.models
|
||||
from django.db import migrations, models
|
||||
import pathlib
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0006_alter_customuser_profile_picture'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customuser',
|
||||
name='profile_picture',
|
||||
field=models.ImageField(default=pathlib.PurePosixPath('profile_pic/default.jpg'), upload_to=account.models.get_profile_pic_path),
|
||||
),
|
||||
]
|
||||
@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fossdb', '0001_initial'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('admin', '0003_logentry_add_action_flag_choices'),
|
||||
('account', '0007_alter_customuser_profile_picture'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='CustomUser',
|
||||
new_name='User',
|
||||
),
|
||||
]
|
||||
@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:53
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fossdb', '0001_initial'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('admin', '0003_logentry_add_action_flag_choices'),
|
||||
('account', '0008_rename_customuser_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='User',
|
||||
new_name='CustomUser',
|
||||
),
|
||||
]
|
||||
@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 13:55
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('admin', '0003_logentry_add_action_flag_choices'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('fossdb', '0001_initial'),
|
||||
('account', '0009_rename_user_customuser'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='CustomUser',
|
||||
new_name='User',
|
||||
),
|
||||
]
|
||||
@ -14,7 +14,7 @@ def get_profile_pic_path(instance, filename) -> Path:
|
||||
|
||||
class User(AbstractUser):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, verbose_name="ID")
|
||||
profile_picture = models.ImageField(upload_to=get_profile_pic_path, default=Path("profile_pics", "default.jpg"))
|
||||
profile_picture = models.ImageField(upload_to=get_profile_pic_path, default="profile_pics/default.jpg")
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
|
||||
@ -20,7 +20,10 @@ class ProjectHostingPlatformInline(admin.TabularInline):
|
||||
|
||||
class ProjectAdmin(admin.ModelAdmin):
|
||||
inlines = [ProjectHostingPlatformInline, ProjectProgrammingLanguageInline]
|
||||
list_display = ("name", "owner", "_languages")
|
||||
list_display = (
|
||||
"name",
|
||||
"owner",
|
||||
)
|
||||
|
||||
def _languages(self, object):
|
||||
return " | ".join([i.programming_language.name for i in object.projectprogramminglanguage_set.all()])
|
||||
|
||||
28
FOSSDB/apps/fossdb/filters.py
Normal file
28
FOSSDB/apps/fossdb/filters.py
Normal file
@ -0,0 +1,28 @@
|
||||
import django_filters
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from .models import Project
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class UserFilter(django_filters.FilterSet):
|
||||
username = django_filters.CharFilter(lookup_expr="icontains")
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("username",)
|
||||
|
||||
|
||||
class ProjectFilter(django_filters.FilterSet):
|
||||
owner = UserFilter()
|
||||
name = django_filters.CharFilter(lookup_expr="icontains")
|
||||
description = django_filters.CharFilter(lookup_expr="icontains")
|
||||
|
||||
class Meta:
|
||||
model = Project
|
||||
fields = (
|
||||
"owner",
|
||||
"name",
|
||||
"description",
|
||||
)
|
||||
@ -1,6 +1,6 @@
|
||||
from django import forms
|
||||
|
||||
from .models import ProjectHostingPlatform, HostingPlatform
|
||||
from .models import HostingPlatform, ProjectHostingPlatform
|
||||
|
||||
|
||||
class HostingPlatformForm(forms.ModelForm):
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 12:54
|
||||
# Generated by Django 4.2.2 on 2023-06-27 16:35
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
@ -75,7 +75,7 @@ class Migration(migrations.Migration):
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(db_index=True, max_length=100, unique=True)),
|
||||
('description', models.TextField(blank=True, default='')),
|
||||
('icon', models.ImageField(blank=True, null=True, upload_to='types/icons/')),
|
||||
('icon', models.ImageField(blank=True, upload_to='types/icons/')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
@ -106,4 +106,12 @@ class Migration(migrations.Migration):
|
||||
name='tag',
|
||||
field=models.ManyToManyField(blank=True, to='fossdb.tag'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='project',
|
||||
constraint=models.UniqueConstraint(fields=('owner', 'name'), name='unique_owner_name'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='operatingsystemversion',
|
||||
constraint=models.UniqueConstraint(fields=('operating_system', 'version'), name='unique_os_version'),
|
||||
),
|
||||
]
|
||||
|
||||
18
FOSSDB/apps/fossdb/migrations/0002_alter_tag_icon.py
Normal file
18
FOSSDB/apps/fossdb/migrations/0002_alter_tag_icon.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 16:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fossdb', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='tag',
|
||||
name='icon',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='types/icons/'),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-27 18:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('fossdb', '0002_alter_tag_icon'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='projectprogramminglanguage',
|
||||
name='percentage',
|
||||
field=models.PositiveIntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@ -6,7 +6,7 @@ from django.db import models
|
||||
|
||||
from .license.models import License
|
||||
from .operating_system.models import OperatingSystemVersion
|
||||
from .programming_language.models import ProgrammingLanguage, ProjectProgrammingLanguage
|
||||
from .programming_language.models import ProgrammingLanguage
|
||||
from .tag.models import Tag
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ class Project(models.Model):
|
||||
license = models.ManyToManyField(License, blank=True)
|
||||
tag = models.ManyToManyField(Tag, blank=True)
|
||||
operating_system = models.ManyToManyField(OperatingSystemVersion, blank=True)
|
||||
programming_language = models.ManyToManyField(ProgrammingLanguage, through=ProjectProgrammingLanguage, blank=True)
|
||||
programming_language = models.ManyToManyField(ProgrammingLanguage, through="ProjectProgrammingLanguage", blank=True)
|
||||
date_created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@property
|
||||
@ -29,4 +29,15 @@ class Project(models.Model):
|
||||
return f"/{self.owner}/{self.name}"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.owner} | {self.name}"
|
||||
return f"{self.owner}/{self.name}"
|
||||
|
||||
class Meta:
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=(
|
||||
"owner",
|
||||
"name",
|
||||
),
|
||||
name="unique_owner_name",
|
||||
),
|
||||
)
|
||||
|
||||
@ -17,3 +17,14 @@ class OperatingSystemVersion(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.operating_system.name} {self.version} {'LTS' if self.is_lts else ''}"
|
||||
|
||||
class Meta:
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=(
|
||||
"operating_system",
|
||||
"version",
|
||||
),
|
||||
name="unique_os_version",
|
||||
),
|
||||
)
|
||||
|
||||
@ -11,7 +11,7 @@ class ProgrammingLanguage(models.Model):
|
||||
class ProjectProgrammingLanguage(models.Model):
|
||||
project = models.ForeignKey("Project", on_delete=models.CASCADE)
|
||||
programming_language = models.ForeignKey(ProgrammingLanguage, on_delete=models.CASCADE)
|
||||
percentage = models.PositiveIntegerField()
|
||||
percentage = models.PositiveIntegerField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.project.owner}/{self.project.name} | {self.programming_language} | {self.percentage}%"
|
||||
|
||||
@ -3,9 +3,9 @@ from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="index"),
|
||||
path("", views.ProjectListView.as_view(), name="index"),
|
||||
path("add/", views.ProjectCreateView.as_view(), name="add-project"),
|
||||
path("<str:owner>/<str:project_name>/", views.ProjectDetailView.as_view(), name="project-detail"),
|
||||
path("<str:owner>/<str:project_name>/update/", views.ProjectUpdateView.as_view(), name="project-update"),
|
||||
path("<str:owner>/<str:project_name>/edit/", views.ProjectUpdateView.as_view(), name="project-update"),
|
||||
path("<str:owner>/<str:project_name>/delete/", views.ProjectDeleteView.as_view(), name="project-delete"),
|
||||
]
|
||||
|
||||
@ -1,58 +1,67 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.forms import inlineformset_factory
|
||||
from django.shortcuts import redirect
|
||||
from django.views.generic import CreateView, DeleteView, DetailView, UpdateView
|
||||
|
||||
from django_filters.views import FilterView
|
||||
|
||||
from .filters import ProjectFilter
|
||||
|
||||
from .forms import ProjectForm
|
||||
from .hosting_platform.forms import HostingPlatformForm
|
||||
|
||||
from .models import Project
|
||||
from .programming_language.forms import ProgrammingLanguageForm
|
||||
from .programming_language.models import ProjectProgrammingLanguage
|
||||
|
||||
ProgrammingLanguageInlineFormset = inlineformset_factory(
|
||||
Project,
|
||||
ProjectProgrammingLanguage,
|
||||
form=ProgrammingLanguageForm,
|
||||
extra=1,
|
||||
)
|
||||
|
||||
|
||||
def index(request):
|
||||
context = {
|
||||
"title": "FOSSDB",
|
||||
"projects": Project.objects.all(),
|
||||
}
|
||||
return render(request, "fossdb/index.html", context)
|
||||
class ProjectListView(FilterView):
|
||||
model = Project
|
||||
template_name = "fossdb/index.html"
|
||||
filterset_class = ProjectFilter
|
||||
context_object_name = "projects"
|
||||
paginate_by = 10 # optional 10 projects a page
|
||||
|
||||
|
||||
class ProjectCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Project
|
||||
form_class = ProjectForm
|
||||
template_name = "fossdb/add_project.html"
|
||||
template_name = "fossdb/create_view.html"
|
||||
login_url = "/login/"
|
||||
redirect_field_name = "redirect_to"
|
||||
|
||||
def form_valid(self, form):
|
||||
response = None
|
||||
with transaction.atomic():
|
||||
form.instance.owner = self.request.user
|
||||
response = super().form_valid(form)
|
||||
|
||||
hosting_platform_form = HostingPlatformForm(self.request.POST, instance=self.object)
|
||||
if hosting_platform_form.is_valid():
|
||||
hosting_platform = hosting_platform_form.save(commit=False)
|
||||
hosting_platform.project = self.object
|
||||
hosting_platform.save()
|
||||
|
||||
# TODO: allow adding multiple languages
|
||||
programming_language_form = ProgrammingLanguageForm(self.request.POST, instance=self.object)
|
||||
if programming_language_form.is_valid():
|
||||
programming_language = programming_language_form.save(commit=False)
|
||||
programming_language.project = self.object
|
||||
programming_language.save()
|
||||
|
||||
return response
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["title"] = "Add project"
|
||||
context["project_form"] = ProjectForm()
|
||||
context["hosting_platform_form"] = HostingPlatformForm()
|
||||
context["programming_language_form"] = ProgrammingLanguageForm()
|
||||
return context
|
||||
data = super().get_context_data(**kwargs)
|
||||
data["hosting_platform"] = HostingPlatformForm(self.request.POST or None, prefix="hosting")
|
||||
data["programming_language"] = ProgrammingLanguageInlineFormset(self.request.POST or None, prefix="language")
|
||||
data["empty_form"] = ProgrammingLanguageInlineFormset(prefix="language_empty")
|
||||
return data
|
||||
|
||||
def form_valid(self, form):
|
||||
context = self.get_context_data()
|
||||
form.instance.owner = self.request.user
|
||||
hosting_platform = context["hosting_platform"]
|
||||
programming_language = context["programming_language"]
|
||||
self.object = form.save()
|
||||
if hosting_platform.is_valid():
|
||||
hosting_platform.instance.project = self.object
|
||||
hosting_platform.save()
|
||||
# TODO: allow adding multiple languages
|
||||
if programming_language.is_valid():
|
||||
for instance in programming_language.save(commit=False):
|
||||
instance.project = self.object
|
||||
instance.save()
|
||||
programming_language.save_m2m()
|
||||
if hosting_platform.is_valid() and programming_language.is_valid():
|
||||
return super().form_valid(form)
|
||||
else:
|
||||
return self.render_to_response(self.get_context_data(form=form))
|
||||
|
||||
|
||||
class ProjectDetailView(DetailView):
|
||||
@ -65,7 +74,7 @@ class ProjectDetailView(DetailView):
|
||||
|
||||
class ProjectUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
|
||||
model = Project
|
||||
template_name = "fossdb/update_view.html"
|
||||
template_name = "fossdb/create_view.html"
|
||||
form_class = ProjectForm
|
||||
slug_field = "name"
|
||||
slug_url_kwarg = "project_name"
|
||||
@ -79,17 +88,11 @@ class ProjectUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
|
||||
return redirect("index")
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
if self.request.POST:
|
||||
context["project_form"] = ProjectForm(self.request.POST, instance=self.object)
|
||||
context["hosting_platform_form"] = HostingPlatformForm(self.request.POST, instance=self.object)
|
||||
context["programming_language_form"] = ProgrammingLanguageForm(self.request.POST, instance=self.object)
|
||||
else:
|
||||
context["project_form"] = ProjectForm(instance=self.object)
|
||||
context["hosting_platform_form"] = HostingPlatformForm(instance=self.object)
|
||||
context["programming_language_form"] = ProgrammingLanguageForm(instance=self.object)
|
||||
|
||||
return context
|
||||
data = super(ProjectUpdateView, self).get_context_data(**kwargs)
|
||||
data["hosting_platform"] = HostingPlatformForm(self.request.POST or None, instance=self.object.projecthostingplatform, prefix="hosting")
|
||||
data["programming_language"] = ProgrammingLanguageInlineFormset(self.request.POST or None, instance=self.object, prefix="language")
|
||||
data["empty_form"] = ProgrammingLanguageInlineFormset(prefix="language_empty")
|
||||
return data
|
||||
|
||||
|
||||
class ProjectDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
|
||||
|
||||
@ -37,6 +37,7 @@ DEBUG = config["DEBUG"]
|
||||
INSTALLED_APPS = [
|
||||
"account",
|
||||
"fossdb",
|
||||
"django_filters",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
|
||||
@ -19,12 +19,11 @@ from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("", include("fossdb.urls")),
|
||||
path("", include("account.urls")),
|
||||
# path("", include("django.contrib.auth.urls")),
|
||||
path("admin/", admin.site.urls),
|
||||
path("", include("django.contrib.auth.urls")),
|
||||
]
|
||||
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
{% extends "layout.html" %}
|
||||
{% load static %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block meta %}{% endblock %}
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ project_form.as_p }}
|
||||
{{ hosting_platform_form.as_table }}
|
||||
<br />
|
||||
{{ programming_language_form.as_table }}
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
34
templates/fossdb/create_view.html
Normal file
34
templates/fossdb/create_view.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% extends "layout.html" %}
|
||||
{% load static %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block meta %}{% endblock %}
|
||||
{% block content %}
|
||||
<form method="post" id="project-form">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
{{ hosting_platform.management_form }}
|
||||
{{ hosting_platform.as_table }}
|
||||
<div id="language-formset">
|
||||
{{ programming_language.management_form }}
|
||||
{% for form in programming_language %}<div class="language-form">{{ form.as_table }}</div>{% endfor %}
|
||||
</div>
|
||||
<!-- This button will trigger the JS to append another language form -->
|
||||
<button type="button" id="add-more">+</button>
|
||||
<!-- Render the empty form, which you'll use as a template for new entries -->
|
||||
<!-- Wrap it in a container so you can reference it by id and hide it -->
|
||||
<div id="empty-form" style="display:none;">{{ empty_form.as_table }}</div>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
<script>
|
||||
document.querySelector("#add-more").addEventListener("click", function() {
|
||||
var formIndex = document.querySelector("#id_language-TOTAL_FORMS").value;
|
||||
var emptyFormDiv = document.querySelector("#empty-form");
|
||||
var newFormHTML = emptyFormDiv.innerHTML.replace(/__prefix__/g, formIndex);
|
||||
var newFormDiv = document.createElement("div");
|
||||
newFormDiv.className = "language-form";
|
||||
newFormDiv.innerHTML = newFormHTML;
|
||||
document.querySelector("#language-formset").append(newFormDiv);
|
||||
document.querySelector("#id_language-TOTAL_FORMS").value = parseInt(formIndex) + 1;
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@ -39,7 +39,6 @@
|
||||
<p>No language</p>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p>{{ project.date_created|date:"d.m.Y, G:i" }}</p>
|
||||
<button>
|
||||
<a href="{% url 'project-update' project.owner project.name %}">Update</a>
|
||||
</button>
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block meta %}{% endblock %}
|
||||
{% block content %}
|
||||
<p>{{ username }}</p>
|
||||
<button>
|
||||
<a href="{% url 'add-project' %}">Add Project</a>
|
||||
</button>
|
||||
@ -10,14 +11,17 @@
|
||||
<a href="/admin">Admin</a>
|
||||
</button>
|
||||
<br />
|
||||
<form action="get">
|
||||
{{ filter.form.as_p }}
|
||||
<button type="submit">Filter</button>
|
||||
</form>
|
||||
{% for project in projects %}
|
||||
<div>
|
||||
<h2>
|
||||
<a href="{{ project.get_absolute_url }}">{{ project.owner }}/{{ project.name }}</a>
|
||||
</h2>
|
||||
<p>{{ project.description }}</p>
|
||||
<a href="{{ project.get_absolute_url }}">{{ project }}</a>
|
||||
</div>
|
||||
<div>{{ project.description }}</div>
|
||||
<hr />
|
||||
{% empty %}
|
||||
<p>No projects yet (</p>
|
||||
<p>No projects found</p>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block title %}Edit {{ project.name }}{% endblock %}
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ project_form.as_p }}
|
||||
{{ hosting_platform_form.as_table }}
|
||||
<br />
|
||||
{{ programming_language_form.as_table }}
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue
Block a user