Skip to content

Commit d728985

Browse files
committed
make certain fields optional for listing
1 parent 1ad8418 commit d728985

5 files changed

Lines changed: 58 additions & 25 deletions

File tree

backend/market/management/commands/generate_listings.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -180,19 +180,6 @@ def handle(self, *args, **options):
180180
"House",
181181
]
182182

183-
neighborhoods = [
184-
"University City",
185-
"Center City",
186-
"Rittenhouse Square",
187-
"Fairmount",
188-
"Graduate Hospital",
189-
"Old City",
190-
"Northern Liberties",
191-
"Fishtown",
192-
"Queen Village",
193-
"South Philadelphia",
194-
]
195-
196183
street_names = [
197184
"Walnut",
198185
"Chestnut",
@@ -234,8 +221,8 @@ def handle(self, *args, **options):
234221
# generate random address
235222
street_number = random.randint(100, 4999)
236223
street = random.choice(street_names)
237-
neighborhood = random.choice(neighborhoods)
238-
address = f"{street_number} {street} St, {neighborhood}, Philadelphia, PA"
224+
225+
street_address = f"{street_number} {street} St, Philadelphia, PA"
239226

240227
# random beds and baths
241228
beds = random.randint(0, 4) # 0 for studio
@@ -271,7 +258,7 @@ def handle(self, *args, **options):
271258
price=price,
272259
negotiable=negotiable,
273260
expires_at=expires_at,
274-
address=address,
261+
street_address=street_address,
275262
beds=beds,
276263
baths=baths,
277264
start_date=start_date,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 5.0.2 on 2026-02-02 20:37
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("market", "0003_delete_phoneverification"),
10+
]
11+
12+
operations = [
13+
migrations.RenameField(
14+
model_name="sublet",
15+
old_name="address",
16+
new_name="street_address",
17+
),
18+
migrations.AlterField(
19+
model_name="listing",
20+
name="expires_at",
21+
field=models.DateTimeField(blank=True, null=True),
22+
),
23+
]

backend/market/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class Meta:
8989
)
9090
negotiable = models.BooleanField(default=True)
9191
created_at = models.DateTimeField(auto_now_add=True)
92-
expires_at = models.DateTimeField()
92+
expires_at = models.DateTimeField(null=True, blank=True)
9393

9494
def __str__(self):
9595
return f"{self.title} by {self.seller}"
@@ -125,7 +125,7 @@ class Condition(models.TextChoices):
125125

126126

127127
class Sublet(Listing):
128-
address = models.CharField(max_length=255)
128+
street_address = models.CharField(max_length=255)
129129
beds = models.PositiveIntegerField()
130130
baths = models.PositiveIntegerField()
131131
start_date = models.DateField()

backend/market/serializers.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
from django.core.exceptions import ValidationError as ModelValidationError
33
from profanity_check import predict
44
from rest_framework.serializers import (
5+
BooleanField,
6+
DateTimeField,
57
ImageField,
68
ModelSerializer,
79
SerializerMethodField,
810
SlugRelatedField,
11+
URLField,
912
ValidationError,
1013
)
1114

@@ -97,7 +100,7 @@ def get_condition(self, obj):
97100
class SubletDataSerializer(ModelSerializer):
98101
class Meta:
99102
model = Sublet
100-
fields = ["address", "beds", "baths", "start_date", "end_date"]
103+
fields = ["street_address", "beds", "baths", "start_date", "end_date"]
101104

102105

103106
# Unified serializer for all listing types (Items and Sublets); used for CRUD operations
@@ -108,16 +111,31 @@ class ListingSerializer(ListingTypeMixin, ModelSerializer):
108111
"model": Item,
109112
},
110113
"sublet": {
111-
"required_fields": ["address", "beds", "baths", "start_date", "end_date"],
114+
"required_fields": [
115+
"street_address",
116+
"beds",
117+
"baths",
118+
"start_date",
119+
"end_date",
120+
],
112121
"model": Sublet,
113122
},
114123
}
115124

116125
images = ListingImageSerializer(many=True, required=False, read_only=True)
117-
tags = SlugRelatedField(many=True, slug_field="name", queryset=Tag.objects.all())
126+
tags = SlugRelatedField(
127+
many=True,
128+
slug_field="name",
129+
queryset=Tag.objects.all(),
130+
required=False,
131+
allow_empty=True,
132+
)
118133
seller = UserSerializer(read_only=True)
119134
listing_type = SerializerMethodField()
120135
additional_data = SerializerMethodField()
136+
external_link = URLField(required=False, allow_blank=True, allow_null=True)
137+
negotiable = BooleanField(required=False, default=True)
138+
expires_at = DateTimeField(required=False, allow_null=True)
121139

122140
class Meta:
123141
model = Listing
@@ -240,7 +258,7 @@ def _create_sublet(self, validated_data, additional_data):
240258
tags = validated_data.pop("tags", None)
241259

242260
sublet = Sublet.objects.create(
243-
address=additional_data.get("address"),
261+
street_address=additional_data.get("street_address"),
244262
beds=additional_data.get("beds"),
245263
baths=additional_data.get("baths"),
246264
start_date=additional_data.get("start_date"),
@@ -297,7 +315,7 @@ def _update_item(self, instance, additional_data):
297315

298316
def _update_sublet(self, instance, additional_data):
299317
sublet = instance.sublet
300-
sublet_fields = ["address", "beds", "baths", "start_date", "end_date"]
318+
sublet_fields = ["street_address", "beds", "baths", "start_date", "end_date"]
301319
for field in sublet_fields:
302320
if field in additional_data:
303321
setattr(sublet, field, additional_data[field])

backend/market/views.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.conf import settings
22
from django.contrib.auth import get_user_model
33
from django.core.cache import cache
4+
from django.db.models import Q
45
from django.utils import timezone
56
from rest_framework import exceptions, mixins, status, viewsets
67
from rest_framework.decorators import api_view, permission_classes
@@ -128,7 +129,7 @@ def get_filter_dict(listing_type):
128129
sublet_filters = {
129130
"beds": "sublet__beds",
130131
"baths": "sublet__baths",
131-
"address": "sublet__address__icontains",
132+
"address": "sublet__street_address__icontains",
132133
}
133134

134135
if listing_type == "item":
@@ -168,7 +169,11 @@ def list(self, request, *args, **kwargs):
168169
if request.query_params.get("seller", "false").lower() == "true":
169170
queryset = queryset.filter(seller=request.user)
170171
else:
171-
queryset = queryset.filter(expires_at__gte=timezone.now())
172+
# Show listings that are not expired, or have no expiration
173+
now = timezone.now()
174+
queryset = queryset.filter(
175+
Q(expires_at__gte=now) | Q(expires_at__isnull=True)
176+
)
172177

173178
page = self.paginate_queryset(queryset)
174179
if page is not None:

0 commit comments

Comments
 (0)