diff --git a/shortener/admin.py b/shortener/admin.py index 22bff5b..5e8a26b 100644 --- a/shortener/admin.py +++ b/shortener/admin.py @@ -2,14 +2,11 @@ from shortener.models import URL - -# Register your models here. -# Register the model with the admin site @admin.register(URL) class ShortenedURLAdmin(admin.ModelAdmin): + # Display the new fields in the admin list view list_display = ('original_url', 'short_code', 'created_at', 'clicks', 'last_accessed') search_fields = ('original_url', 'short_code') list_filter = ('created_at', 'last_accessed') - readonly_fields = ('clicks', 'last_accessed') diff --git a/shortener/forms.py b/shortener/forms.py deleted file mode 100644 index 6037b82..0000000 --- a/shortener/forms.py +++ /dev/null @@ -1,10 +0,0 @@ -from django import forms - -class URLForm(forms.Form): - original_url = forms.URLField( - label='Enter URL to shorten', - widget=forms.URLInput(attrs={ - 'class': 'w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-emerald-600', - 'placeholder': 'https://example.com' - }) - ) diff --git a/shortener/models.py b/shortener/models.py index 6ebcb5b..499840a 100644 --- a/shortener/models.py +++ b/shortener/models.py @@ -1,21 +1,28 @@ from django.db import models from django.utils import timezone -# Create your models here. class URL(models.Model): - original_url = models.URLField() - short_code = models.CharField(max_length=10, unique=True) - created_at = models.DateTimeField(auto_now_add=True) + """ + The main model for storing URL shortening data. + """ - last_accessed = models.DateTimeField(null=True, blank=True) - clicks = models.PositiveIntegerField(default=0) + original_url = models.URLField() # Original URL + short_code = models.CharField(max_length=10, unique=True) # Short code for the URL + created_at = models.DateTimeField(auto_now_add=True) # Creation timestamp + + last_accessed = models.DateTimeField(null=True, blank=True) # Last accessed timestamp + clicks = models.PositiveIntegerField(default=0) # Number of times the URL was accessed def __str__(self): return f'{self.short_code} -> {self.original_url}' - # Method to update access info def record_access(self): + """ + Every time the URL is accessed + this method should be called to update + the last accessed timestamp and the number of clicks. + """ self.last_accessed = timezone.now() self.clicks += 1 self.save(update_fields=['last_accessed', 'clicks']) diff --git a/shortener/utils.py b/shortener/utils.py index bc2e4ee..6965b30 100644 --- a/shortener/utils.py +++ b/shortener/utils.py @@ -5,7 +5,6 @@ def generate_short_code(initial_length: int = 6, max_length: int = 10) -> str: """ Generate a random short code for the URL. Automatically increases length if no unique code is found. - :param initial_length: Starting length for the short code. :param max_length: Maximum length the short code can grow to. :return: A unique short code as a string. diff --git a/shortener/views.py b/shortener/views.py index 4234cbf..9e281cb 100644 --- a/shortener/views.py +++ b/shortener/views.py @@ -1,8 +1,9 @@ from django.shortcuts import render, redirect, get_object_or_404 from .models import URL from .utils import generate_short_code +from django.http import HttpRequest, HttpResponse -def shorten_url(request): +def shorten_url(request: HttpRequest) -> HttpResponse: if request.method == 'POST': # Retrieve the original URL from POST data original_url = request.POST.get('original_url') @@ -29,7 +30,7 @@ def shorten_url(request): # Render the form if the request method is not POST return render(request, 'shortener/index.html') -def shortened_url(request, short_code): +def shortened_url(request: HttpRequest, short_code: str) -> HttpResponse: """View to display the shortened URL.""" # Validate the short code exists in the database @@ -37,7 +38,7 @@ def shortened_url(request, short_code): return render(request, 'shortener/shortened.html', {'short_url': request.build_absolute_uri(f"/{short_code}")}) -def redirect_url(request, short_code): +def redirect_url(request: HttpRequest, short_code: str) -> HttpResponse: url = get_object_or_404(URL, short_code=short_code) # Update the access information