Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added lettings/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions lettings/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin
from .models import Letting, Address

# Register your models here.
admin.site.register(Letting)
admin.site.register(Address)
6 changes: 6 additions & 0 deletions lettings/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class LettingsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'lettings'
36 changes: 36 additions & 0 deletions lettings/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 4.2.11 on 2025-05-16 11:59

import django.core.validators
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Address',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('number', models.PositiveIntegerField(validators=[django.core.validators.MaxValueValidator(9999)])),
('street', models.CharField(max_length=64)),
('city', models.CharField(max_length=64)),
('state', models.CharField(max_length=2, validators=[django.core.validators.MinLengthValidator(2)])),
('zip_code', models.PositiveIntegerField(validators=[django.core.validators.MaxValueValidator(99999)])),
('country_iso_code', models.CharField(max_length=3, validators=[django.core.validators.MinLengthValidator(3)])),
],
),
migrations.CreateModel(
name='Letting',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=256)),
('address', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='lettings.address')),
],
),
]
36 changes: 36 additions & 0 deletions lettings/migrations/0002_copy_data_from_old_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.db import migrations

def copy_lettings_and_addresses(apps, schema_editor):
OldAddress = apps.get_model('oc_lettings_site', 'Address')
OldLetting = apps.get_model('oc_lettings_site', 'Letting')
NewAddress = apps.get_model('lettings', 'Address')
NewLetting = apps.get_model('lettings', 'Letting')

old_to_new_address = {}
for old_addr in OldAddress.objects.all():
new_addr = NewAddress.objects.create(
number=old_addr.number,
street=old_addr.street,
city=old_addr.city,
state=old_addr.state,
zip_code=old_addr.zip_code,
country_iso_code=old_addr.country_iso_code,
)
old_to_new_address[old_addr.id] = new_addr

# Copier les lettings
for old_letting in OldLetting.objects.all():
NewLetting.objects.create(
title=old_letting.title,
address=old_to_new_address.get(old_letting.address_id)
)

class Migration(migrations.Migration):
dependencies = [
('lettings', '0001_initial'),
('oc_lettings_site', '__first__'),
]

operations = [
migrations.RunPython(copy_lettings_and_addresses),
]
Empty file added lettings/migrations/__init__.py
Empty file.
42 changes: 42 additions & 0 deletions lettings/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.db import models
from django.core.validators import MaxValueValidator, MinLengthValidator


class Address(models.Model):
"""
Model representing a physical address.

This model stores :
number, street, city, state, zip code, and country code.
"""
number = models.PositiveIntegerField(validators=[MaxValueValidator(9999)])
street = models.CharField(max_length=64)
city = models.CharField(max_length=64)
state = models.CharField(max_length=2, validators=[MinLengthValidator(2)])
zip_code = models.PositiveIntegerField(validators=[MaxValueValidator(99999)])
country_iso_code = models.CharField(max_length=3, validators=[MinLengthValidator(3)])

def __str__(self):
"""
Returns a string representation of the address.

Returns:
str: The address in the format 'number street'
"""
return f'{self.number} {self.street}'


class Letting(models.Model):
"""
Model representing a property letting.

This model stores title and associated addresses.
"""
title = models.CharField(max_length=256)
address = models.OneToOneField(Address, on_delete=models.CASCADE)

def __str__(self):
"""
Returns the title of the letting.
"""
return self.title
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h1 class="page-header-ui-title mb-3 display-6">Lettings</h1>
<ul class="list-group list-group-flush list-group-careers">
{% for letting in lettings_list %}
<li class="list-group-item">
<a href="{% url 'letting' letting_id=letting.id %}">{{ letting.title }}</a>
<a href="{% url 'lettings:letting' letting_id=letting.id %}">{{ letting.title }}</a>
</li>
{% endfor %}
</ul>
Expand All @@ -36,10 +36,10 @@ <h1 class="page-header-ui-title mb-3 display-6">Lettings</h1>
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'index' %}">
Home
</a>
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'profiles_index' %}">
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'profiles:index' %}">
Profiles
</a>
</div>
</div>

{% endblock %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ <h1 class="page-header-ui-title mb-3 display-6">{{ title }}</h1>

<div class="container px-5 py-5 text-center">
<div class="justify-content-center">
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'lettings_index' %}">
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'lettings:index' %}">
<i class="ms-2" data-feather="arrow-right"></i>
Back
</a>
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'index' %}">
Home
</a>
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'profiles_index' %}">
<a class="btn fw-500 ms-lg-4 btn-primary px-10" href="{% url 'profiles:index' %}">
Profiles
</a>
</div>
</div>

{% endblock %}
{% endblock %}
3 changes: 3 additions & 0 deletions lettings/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
9 changes: 9 additions & 0 deletions lettings/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import path
from . import views

app_name = 'lettings'

urlpatterns = [
path('', views.index, name='index'),
path('<int:letting_id>/', views.letting, name='letting'),
]
36 changes: 36 additions & 0 deletions lettings/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.shortcuts import render, get_object_or_404
from .models import Letting

def index(request):
"""
View function for the lettings list page.

Args:
request: The HTTP request object
Returns:
template 'lettings/index.html' with a list of all lettings
"""
lettings_list = Letting.objects.all()
context = {'lettings_list': lettings_list}
return render(request, 'lettings/index.html', context)

def letting(request, letting_id):
"""
View function for displaying a specific letting's details.

Args:
request: The HTTP request object
letting_id: The ID of the letting to display

Returns:
template 'lettings/letting.html' with the requested letting's details

Raises:
Http404: If the letting with the given ID doesn't exist
"""
letting = get_object_or_404(Letting, id=letting_id)
context = {
'title': letting.title,
'address': letting.address,
}
return render(request, 'lettings/letting.html', context)
Binary file modified oc-lettings-site.sqlite3
Binary file not shown.
10 changes: 1 addition & 9 deletions oc_lettings_site/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
from django.contrib import admin

from .models import Letting
from .models import Address
from .models import Profile


admin.site.register(Letting)
admin.site.register(Address)
admin.site.register(Profile)
# Les modèles ont été déplacés dans les applications 'lettings' et 'profiles'.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 4.2.11 on 2025-05-16 12:00

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('oc_lettings_site', '0001_initial'),
]

operations = [
migrations.RemoveField(
model_name='letting',
name='address',
),
migrations.RemoveField(
model_name='profile',
name='user',
),
migrations.DeleteModel(
name='Address',
),
migrations.DeleteModel(
name='Letting',
),
migrations.DeleteModel(
name='Profile',
),
]
32 changes: 1 addition & 31 deletions oc_lettings_site/models.py
Original file line number Diff line number Diff line change
@@ -1,31 +1 @@
from django.db import models
from django.core.validators import MaxValueValidator, MinLengthValidator
from django.contrib.auth.models import User


class Address(models.Model):
number = models.PositiveIntegerField(validators=[MaxValueValidator(9999)])
street = models.CharField(max_length=64)
city = models.CharField(max_length=64)
state = models.CharField(max_length=2, validators=[MinLengthValidator(2)])
zip_code = models.PositiveIntegerField(validators=[MaxValueValidator(99999)])
country_iso_code = models.CharField(max_length=3, validators=[MinLengthValidator(3)])

def __str__(self):
return f'{self.number} {self.street}'


class Letting(models.Model):
title = models.CharField(max_length=256)
address = models.OneToOneField(Address, on_delete=models.CASCADE)

def __str__(self):
return self.title


class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
favorite_city = models.CharField(max_length=64, blank=True)

def __str__(self):
return self.user.username
# Les modèles ont été déplacés dans les applications 'lettings' et 'profiles'.
6 changes: 4 additions & 2 deletions oc_lettings_site/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['localhost', '127.0.0.1']


# Application definition
Expand All @@ -28,6 +28,8 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'lettings',
'profiles',
]

MIDDLEWARE = [
Expand All @@ -45,7 +47,7 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'DIRS': [os.path.join(BASE_DIR, 'oc_lettings_site/templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand Down
12 changes: 12 additions & 0 deletions oc_lettings_site/templates/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends 'base.html' %}

{% block title %}Page non trouvée{% endblock %}

{% block content %}
<div class="container text-center mt-5">
<h1 class="display-1">404</h1>
<h2 class="mb-4">Oops !</h2>
<p class="lead">La page que vous recherchez n'existe pas.</p>
<a href="{% url 'index' %}" class="btn btn-primary mt-3">Retour à l'accueil</a>
</div>
{% endblock %}
13 changes: 13 additions & 0 deletions oc_lettings_site/templates/500.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% extends 'base.html' %}

{% block title %}Erreur serveur{% endblock %}

{% block content %}
<div class="container text-center mt-5">
<h1 class="display-1">500</h1>
<h2 class="mb-4">Oops !</h2>
<p class="lead">Une erreur inattendue s'est produite.</p>
<p>Notre équipe technique a été notifiée et travaille à résoudre le problème.</p>
<a href="{% url 'index' %}" class="btn btn-primary mt-3">Retour à l'accueil</a>
</div>
{% endblock %}
6 changes: 3 additions & 3 deletions templates/base.html → oc_lettings_site/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
<div class="container">
<a class="navbar-brand" href="{% url 'index'%}"><img class="img-responsive" src="{% static 'assets/img/logo.png' %}" width="70px" height="70px" alt="Logo Orange County Lettings"/></a>
<div>
<a class="btn fw-500 ms-lg-4 btn-primary" href="{% url 'profiles_index' %}">
<a class="btn fw-500 ms-lg-4 btn-primary" href="{% url 'profiles:index' %}">
Profiles
</a>
<a class="btn fw-500 ms-lg-4 btn-primary" href="{% url 'lettings_index' %}">
<a class="btn fw-500 ms-lg-4 btn-primary" href="{% url 'lettings:index' %}">
Lettings
</a>
</div>
Expand Down Expand Up @@ -64,4 +64,4 @@
});
</script>
</body>
</html>
</html>
Loading