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 django.contrib import admin
from .host.models import HostingPlatform, ProjectHostingPlatform from .hosting_platform.models import HostingPlatform, ProjectHostingPlatform
from .language.models import ProgrammingLanguage, ProjectProgrammingLanguage
from .license.models import License from .license.models import License
from .models import Project from .models import Project
from .operating_system.models import OperatingSystem, OperatingSystemVersion
from .programming_language.models import ProgrammingLanguage, ProjectProgrammingLanguage
from .tag.models import Tag from .tag.models import Tag
@ -12,24 +13,26 @@ class ProjectProgrammingLanguageInline(admin.TabularInline):
extra = 1 extra = 1
class ProjectHostingPlatformInline(admin.TabularInline):
model = ProjectHostingPlatform
extra = 1
class ProjectAdmin(admin.ModelAdmin): class ProjectAdmin(admin.ModelAdmin):
inlines = [ProjectProgrammingLanguageInline, ProjectHostingPlatformInline] inlines = [ProjectProgrammingLanguageInline]
list_display = ("author", "name", "_languages", "_hosting_platform") list_display = ("name", "author", "_languages", "hosting_platform")
def _languages(self, object): def _languages(self, object):
return " | ".join([i.language.language for i in object.projectprogramminglanguage_set.all()]) return " | ".join(
[i.language.name 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()])
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(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 django import forms
from .hosting_platform.models import HostingPlatform, ProjectHostingPlatform
from .models import Project from .models import Project
class ProjectForm(forms.ModelForm): class ProjectForm(forms.ModelForm):
hosting_platform = forms.ModelChoiceField(queryset=HostingPlatform.objects.all())
url = forms.CharField(max_length=100)
class Meta: class Meta:
model = Project model = Project
fields = ["name", "description", "licenses"] fields = (
"name",
"description",
"license",
"tag",
"operating_system",
)
exclude = ("hosting_platform",)
widgets = { widgets = {
"name": forms.TextInput(attrs={ "name": forms.TextInput(
"class": "form-control", attrs={
"placeholder": "Project name", "class": "form-control",
}), "placeholder": "Project name",
"description": forms.Textarea(attrs={ }
"class": "form-control", ),
"placeholder": "Description", "description": forms.Textarea(
}), attrs={
"licenses": forms.CheckboxSelectMultiple(), "class": "form-control",
"placeholder": "Description",
}
),
"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.conf import settings
from django.db import models from django.db import models
from .host.models import HostingPlatform from .hosting_platform.models import ProjectHostingPlatform
from .language.models import ProgrammingLanguage
from .license.models import License from .license.models import License
from .operating_system.models import OperatingSystem from .operating_system.models import OperatingSystemVersion
from .star.models import Star from .programming_language.models import ProgrammingLanguage
from .tag.models import Tag from .tag.models import Tag
User = settings.AUTH_USER_MODEL User = settings.AUTH_USER_MODEL
class Project(models.Model): class Project(models.Model):
uuid = models.UUIDField( uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True) author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
description = models.TextField(blank=True, default="") description = models.TextField(blank=True, default="")
licenses = models.ManyToManyField(License) license = models.ManyToManyField(License, blank=True)
programming_languages = models.ManyToManyField( programming_language = models.ManyToManyField(
ProgrammingLanguage, through="ProjectProgrammingLanguage", related_name="projects") ProgrammingLanguage,
hosting_platform = models.ManyToManyField( through="ProjectProgrammingLanguage",
HostingPlatform, through="ProjectHostingPlatform", related_name="projects") related_name="projects",
tag = models.ManyToManyField(Tag) blank=True,
os = models.ManyToManyField(OperatingSystem) )
star = models.ManyToManyField(Star, related_name="projects_star") 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) date_created = models.DateTimeField(auto_now_add=True)
@property @property
def star_amount(self): def star_amount(self):
return self.star.count() return self.star.count()
def get_absolute_url(self): @property
def absolute_url(self):
return f"/{self.author.name}/{self.name}" return f"/{self.author.name}/{self.name}"
def __str__(self): def __str__(self):
@ -41,6 +44,5 @@ class Project(models.Model):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.uuid: if not self.uuid:
self.uuid = uuid.uuid3( self.uuid = uuid.uuid3(uuid.uuid4(), f"{self.author.username}-{self.name}")
uuid.uuid4(), f"{self.author.username}-{self.name}")
super().save(*args, **kwargs) super().save(*args, **kwargs)

View File

@ -1,12 +1,38 @@
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.views.generic import CreateView, DeleteView, DetailView, UpdateView
from .forms import ProjectForm from .forms import ProjectForm
from .host.forms import ProjectHostingPlatformFormSet from .hosting_platform.models import ProjectHostingPlatform
from .language.forms import ProjectProgrammingLanguageFormSet
from .models import Project 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): def index(request):
context = { context = {
"title": "FOSSDB", "title": "FOSSDB",
@ -15,36 +41,8 @@ def index(request):
return render(request, "fossdb/index.html", context) 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 %} {% block content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
{{ project_form.as_p }} {{ 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 }}
<button type="submit">Post</button> <button type="submit">Post</button>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -11,26 +11,12 @@
</button> </button>
<br> <br>
{% for project in projects %} {% for project in projects %}
<b>@{{ project.author.username }}</b> <b>@{{ project.owner }}</b>
<h4>{{ project.name }}</h4> <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> <br>
<a href="{{ project.get_absolute_url }}">
<button>Read more</button>
</a>
<p>{{ project.date_created }}</p> <p>{{ project.date_created }}</p>
{% empty %} {% empty %}
<p>No projects yet (</p> <p>No projects yet (</p>