Fix HostingPlatform

Users can add projects and associated hosting platforms and respective URLs at the same time.
This commit is contained in:
Kristofers Solo 2023-06-25 13:46:46 +00:00
parent 12b93544f9
commit bfc25c582f
9 changed files with 116 additions and 143 deletions

View File

@ -1,9 +1,10 @@
from django.contrib import admin
from .host.models import HostingPlatform, ProjectHostingPlatform
from .language.models import ProgrammingLanguage, ProjectProgrammingLanguage
from .hosting_platform.models import HostingPlatform, ProjectHostingPlatform
from .license.models import License
from .models import Project
from .operating_system.models import OperatingSystem, OperatingSystemVersion
from .programming_language.models import ProgrammingLanguage, ProjectProgrammingLanguage
from .tag.models import Tag
@ -12,24 +13,26 @@ class ProjectProgrammingLanguageInline(admin.TabularInline):
extra = 1
class ProjectHostingPlatformInline(admin.TabularInline):
model = ProjectHostingPlatform
extra = 1
class ProjectAdmin(admin.ModelAdmin):
inlines = [ProjectProgrammingLanguageInline, ProjectHostingPlatformInline]
list_display = ("author", "name", "_languages", "_hosting_platform")
inlines = [ProjectProgrammingLanguageInline]
list_display = ("name", "author", "_languages", "hosting_platform")
def _languages(self, object):
return " | ".join([i.language.language for i in object.projectprogramminglanguage_set.all()])
def _hosting_platform(self, object):
return " | ".join([i.hosting_platform.hosting_platform for i in object.projecthostingplatform_set.all()])
return " | ".join(
[i.language.name for i in object.projectprogramminglanguage_set.all()]
)
admin.site.register(HostingPlatform)
models = (
HostingPlatform,
# ProjectHostingPlatform, # WARNING: remove this
License,
ProgrammingLanguage,
Tag,
OperatingSystem,
OperatingSystemVersion,
)
for model in models:
admin.site.register(model)
admin.site.register(Project, ProjectAdmin)
admin.site.register(License)
admin.site.register(ProgrammingLanguage)
admin.site.register(Tag)

View File

@ -1,22 +1,40 @@
from django import forms
from .hosting_platform.models import HostingPlatform, ProjectHostingPlatform
from .models import Project
class ProjectForm(forms.ModelForm):
hosting_platform = forms.ModelChoiceField(queryset=HostingPlatform.objects.all())
url = forms.CharField(max_length=100)
class Meta:
model = Project
fields = ["name", "description", "licenses"]
fields = (
"name",
"description",
"license",
"tag",
"operating_system",
)
exclude = ("hosting_platform",)
widgets = {
"name": forms.TextInput(attrs={
"name": forms.TextInput(
attrs={
"class": "form-control",
"placeholder": "Project name",
}),
"description": forms.Textarea(attrs={
}
),
"description": forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Description",
}),
"licenses": forms.CheckboxSelectMultiple(),
}
),
"license": forms.CheckboxSelectMultiple(),
"tag": forms.CheckboxSelectMultiple(),
"operating_system": forms.CheckboxSelectMultiple(),
}

View File

@ -1,22 +0,0 @@
from django import forms
from fossdb.models import Project
from .models import HostingPlatform, ProjectHostingPlatform
class HostingPlatformForm(forms.ModelForm):
url = forms.URLField()
class Meta:
model = HostingPlatform
fields = ["hosting_platform", "url"]
ProjectHostingPlatformFormSet = forms.inlineformset_factory(
Project,
ProjectHostingPlatform,
form=HostingPlatformForm,
extra=1,
can_delete=False
)

View File

@ -1,17 +0,0 @@
from django.db import models
class HostingPlatform(models.Model):
hosting_platform = models.CharField(max_length=100)
def __str__(self):
return self.hosting_platform
class ProjectHostingPlatform(models.Model):
project = models.ForeignKey("Project", on_delete=models.CASCADE)
hosting_platform = models.ForeignKey(HostingPlatform, on_delete=models.CASCADE)
url = models.URLField()
def __str__(self):
return f"{self.project} | {self.hosting_platform}"

View File

@ -0,0 +1,16 @@
from django.db import models
class HostingPlatform(models.Model):
name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.name
class ProjectHostingPlatform(models.Model):
hosting_platform = models.ForeignKey(HostingPlatform, on_delete=models.CASCADE)
url = models.URLField(unique=True)
def __str__(self):
return self.url

View File

@ -3,37 +3,40 @@ import uuid
from django.conf import settings
from django.db import models
from .host.models import HostingPlatform
from .language.models import ProgrammingLanguage
from .hosting_platform.models import ProjectHostingPlatform
from .license.models import License
from .operating_system.models import OperatingSystem
from .star.models import Star
from .operating_system.models import OperatingSystemVersion
from .programming_language.models import ProgrammingLanguage
from .tag.models import Tag
User = settings.AUTH_USER_MODEL
class Project(models.Model):
uuid = models.UUIDField(
primary_key=True, default=uuid.uuid4, editable=False)
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)
name = models.CharField(max_length=255)
description = models.TextField(blank=True, default="")
licenses = models.ManyToManyField(License)
programming_languages = models.ManyToManyField(
ProgrammingLanguage, through="ProjectProgrammingLanguage", related_name="projects")
hosting_platform = models.ManyToManyField(
HostingPlatform, through="ProjectHostingPlatform", related_name="projects")
tag = models.ManyToManyField(Tag)
os = models.ManyToManyField(OperatingSystem)
star = models.ManyToManyField(Star, related_name="projects_star")
license = models.ManyToManyField(License, blank=True)
programming_language = models.ManyToManyField(
ProgrammingLanguage,
through="ProjectProgrammingLanguage",
related_name="projects",
blank=True,
)
hosting_platform = models.ForeignKey(
ProjectHostingPlatform, on_delete=models.CASCADE
)
tag = models.ManyToManyField(Tag, blank=True)
operating_system = models.ManyToManyField(OperatingSystemVersion, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
@property
def star_amount(self):
return self.star.count()
def get_absolute_url(self):
@property
def absolute_url(self):
return f"/{self.author.name}/{self.name}"
def __str__(self):
@ -41,6 +44,5 @@ class Project(models.Model):
def save(self, *args, **kwargs):
if not self.uuid:
self.uuid = uuid.uuid3(
uuid.uuid4(), f"{self.author.username}-{self.name}")
self.uuid = uuid.uuid3(uuid.uuid4(), f"{self.author.username}-{self.name}")
super().save(*args, **kwargs)

View File

@ -1,12 +1,38 @@
from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import redirect, render
from django.views.generic import CreateView, DeleteView, DetailView, UpdateView
from .forms import ProjectForm
from .host.forms import ProjectHostingPlatformFormSet
from .language.forms import ProjectProgrammingLanguageFormSet
from .hosting_platform.models import ProjectHostingPlatform
from .models import Project
@login_required(login_url="login/")
@permission_required("fossdb.add_project", login_url="login/", raise_exception=True)
def add_project(request):
form = ProjectForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
project = form.save(commit=False)
project.author = request.user
project_hosting_platform = ProjectHostingPlatform.objects.create(
hosting_platform=form.cleaned_data["hosting_platform"],
url=form.cleaned_data["url"],
)
project.hosting_platform = project_hosting_platform
project.save()
form.save_m2m()
return redirect("index")
context = {
"title": "Add project",
"form": form,
}
return render(request, "fossdb/add_project.html", context)
def index(request):
context = {
"title": "FOSSDB",
@ -15,36 +41,8 @@ def index(request):
return render(request, "fossdb/index.html", context)
@login_required(login_url="login/")
@permission_required("fossdb.add_project", login_url="login/", raise_exception=True)
def add_project(request):
if request.method == "POST":
project_form = ProjectForm(request.POST)
language_formset = ProjectProgrammingLanguageFormSet(request.POST, instance=Project())
host_formset = ProjectHostingPlatformFormSet(request.POST, instance=Project())
if project_form.is_valid() and language_formset.is_valid() and host_formset.is_valid():
project = project_form.save(commit=False)
project.author = request.user
project.save()
language_formset.instance = project
language_formset.save()
host_formset.instance = project
host_formset.save()
project_form.save_m2m()
return redirect("/")
else:
project_form = ProjectForm()
language_formset = ProjectProgrammingLanguageFormSet()
host_formset = ProjectHostingPlatformFormSet()
context = {
"title": "Add project",
"project_form": project_form,
"language_formset": language_formset,
"host_formset": host_formset,
}
return render(request, "fossdb/add_project.html", context)

View File

@ -5,18 +5,7 @@
{% block content %}
<form method="post">
{% csrf_token %}
{{ project_form.as_p }}
<table>
{{ language_formset.management_form }}
{% for form in language_formset %}
<tr>
<td>{{ form.language.label_tag }}</td>
<td>{{ form.language }}</td>
<td>{{ form.percentage }}</td>
</tr>
{% endfor %}
</table>
{{ host_formset.as_p }}
{{ form.as_p }}
<button type="submit">Post</button>
</form>
{% endblock %}

View File

@ -11,26 +11,12 @@
</button>
<br>
{% for project in projects %}
<b>@{{ project.author.username }}</b>
<b>@{{ project.owner }}</b>
<h4>{{ project.name }}</h4>
<p>{{ project.description }}</p>
<ul>
{% for license in project.licenses.all %}
<li>
<a href="{{ license.url }}">{{ license.short_name }}</a>
</li>
{% empty %}
<p>No license</p>
{% endfor %}
</ul>
<ul>
{% for language in project.projectprogramminglanguage_set.all %}
<li>{{ language.language }} | {{ language.percentage }}&#37;</li>
{% empty %}
<p>No language</p>
{% endfor %}
</ul>
<br>
<a href="{{ project.get_absolute_url }}">
<button>Read more</button>
</a>
<p>{{ project.date_created }}</p>
{% empty %}
<p>No projects yet (</p>