diff --git a/backend/market/admin.py b/backend/market/admin.py
index db11398e..48b42d8d 100644
--- a/backend/market/admin.py
+++ b/backend/market/admin.py
@@ -1,19 +1,21 @@
from django.contrib import admin
from django.utils.html import mark_safe
-from market.models import Amenity, Offer, Sublet, SubletImage
+from market.models import Tag, Category, Offer, Item, Sublet, ItemImage
-class SubletAdmin(admin.ModelAdmin):
+class ItemAdmin(admin.ModelAdmin):
def image_tag(self, instance):
images = ['
' for image in instance.images.all()]
return mark_safe("
".join(images))
- image_tag.short_description = "Sublet Images"
+ image_tag.short_description = "Item Images"
readonly_fields = ("image_tag",)
admin.site.register(Offer)
-admin.site.register(Amenity)
-admin.site.register(Sublet, SubletAdmin)
-admin.site.register(SubletImage)
+admin.site.register(Tag)
+admin.site.register(Category)
+admin.site.register(Item, ItemAdmin)
+admin.site.register(Sublet)
+admin.site.register(ItemImage)
diff --git a/backend/market/migrations/0001_initial.py b/backend/market/migrations/0001_initial.py
new file mode 100644
index 00000000..e9b4757f
--- /dev/null
+++ b/backend/market/migrations/0001_initial.py
@@ -0,0 +1,168 @@
+# Generated by Django 5.0.2 on 2024-10-25 16:41
+
+import django.db.models.deletion
+import phonenumber_field.modelfields
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name="Category",
+ fields=[
+ ("name", models.CharField(max_length=50, primary_key=True, serialize=False)),
+ ],
+ ),
+ migrations.CreateModel(
+ name="Tag",
+ fields=[
+ ("name", models.CharField(max_length=255, primary_key=True, serialize=False)),
+ ],
+ ),
+ migrations.CreateModel(
+ name="Item",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("title", models.CharField(max_length=255)),
+ ("description", models.TextField(blank=True, null=True)),
+ ("external_link", models.URLField(blank=True, max_length=255, null=True)),
+ ("price", models.IntegerField()),
+ ("negotiable", models.BooleanField(default=True)),
+ ("used", models.BooleanField(blank=True, null=True)),
+ ("created_at", models.DateTimeField(auto_now_add=True)),
+ ("expires_at", models.DateTimeField()),
+ (
+ "category",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="items",
+ to="market.category",
+ ),
+ ),
+ (
+ "favorites",
+ models.ManyToManyField(
+ blank=True, related_name="items_favorited", to=settings.AUTH_USER_MODEL
+ ),
+ ),
+ (
+ "seller",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
+ ),
+ ),
+ ],
+ ),
+ migrations.CreateModel(
+ name="ItemImage",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("image", models.ImageField(upload_to="marketplace/images")),
+ (
+ "item",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="images",
+ to="market.item",
+ ),
+ ),
+ ],
+ ),
+ migrations.CreateModel(
+ name="Offer",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("email", models.EmailField(blank=True, max_length=255, null=True)),
+ (
+ "phone_number",
+ phonenumber_field.modelfields.PhoneNumberField(
+ blank=True, max_length=128, null=True, region=None
+ ),
+ ),
+ ("message", models.CharField(blank=True, max_length=255)),
+ ("created_date", models.DateTimeField(auto_now_add=True)),
+ (
+ "item",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="offers",
+ to="market.item",
+ ),
+ ),
+ (
+ "user",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="offers_made_market",
+ to=settings.AUTH_USER_MODEL,
+ ),
+ ),
+ ],
+ ),
+ migrations.AddField(
+ model_name="item",
+ name="buyers",
+ field=models.ManyToManyField(
+ blank=True,
+ related_name="items_offered",
+ through="market.Offer",
+ to=settings.AUTH_USER_MODEL,
+ ),
+ ),
+ migrations.CreateModel(
+ name="Sublet",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ("address", models.CharField(max_length=255)),
+ ("beds", models.IntegerField()),
+ ("baths", models.IntegerField()),
+ ("start_date", models.DateTimeField()),
+ ("end_date", models.DateTimeField()),
+ (
+ "item",
+ models.OneToOneField(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="sublet",
+ to="market.item",
+ ),
+ ),
+ ],
+ ),
+ migrations.AddField(
+ model_name="item",
+ name="tags",
+ field=models.ManyToManyField(blank=True, related_name="items", to="market.tag"),
+ ),
+ migrations.AddConstraint(
+ model_name="offer",
+ constraint=models.UniqueConstraint(fields=("user", "item"), name="unique_offer_market"),
+ ),
+ ]
diff --git a/backend/market/models.py b/backend/market/models.py
index 6b0cbbbc..20fa43bd 100644
--- a/backend/market/models.py
+++ b/backend/market/models.py
@@ -8,9 +8,9 @@
class Offer(models.Model):
class Meta:
- constraints = [models.UniqueConstraint(fields=["user", "item"], name="unique_offer")]
+ constraints = [models.UniqueConstraint(fields=["user", "item"], name="unique_offer_market")]
- user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="offers_made")
+ user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="offers_made_market")
item = models.ForeignKey("Item", on_delete=models.CASCADE, related_name="offers")
email = models.EmailField(max_length=255, null=True, blank=True)
phone_number = PhoneNumberField(null=True, blank=True)
@@ -59,11 +59,7 @@ class Item(models.Model):
User, through=Offer, related_name="items_offered", blank=True
)
tags = models.ManyToManyField(Tag, related_name="items", blank=True)
- category = models.CharField(
- max_length=50,
- choices=Category.choices,
- default=Category.OTHER,
- )
+ category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="items")
favorites = models.ManyToManyField(User, related_name="items_favorited", blank=True)
title = models.CharField(max_length=255)
diff --git a/backend/market/permissions.py b/backend/market/permissions.py
index 594a7148..b62b2dbc 100644
--- a/backend/market/permissions.py
+++ b/backend/market/permissions.py
@@ -49,7 +49,7 @@ def has_permission(self, request, view):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
- # Check if the user owns the sublet when getting list
+ # Check if the user owns the item when getting list
return obj.seller == request.user
# This is redundant, here for safety
return obj.user == request.user
diff --git a/backend/market/serializers.py b/backend/market/serializers.py
index c8967cde..06d7e1db 100644
--- a/backend/market/serializers.py
+++ b/backend/market/serializers.py
@@ -2,12 +2,18 @@
from profanity_check import predict
from rest_framework import serializers
-from market.models import Amenity, Offer, Sublet, SubletImage
+from market.models import Tag, Category, Offer, Item, Sublet, ItemImage
-class AmenitySerializer(serializers.ModelSerializer):
+class TagSerializer(serializers.ModelSerializer):
class Meta:
- model = Amenity
+ model = Tag
+ fields = "__all__"
+
+
+class CategorySerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Category
fields = "__all__"
@@ -25,16 +31,16 @@ def create(self, validated_data):
# Create/Update Image Serializer
-class SubletImageSerializer(serializers.ModelSerializer):
+class ItemImageSerializer(serializers.ModelSerializer):
image = serializers.ImageField(write_only=True, required=False, allow_null=True)
class Meta:
- model = SubletImage
- fields = ["sublet", "image"]
+ model = ItemImage
+ fields = ["item", "image"]
# Browse images
-class SubletImageURLSerializer(serializers.ModelSerializer):
+class ItemImageURLSerializer(serializers.ModelSerializer):
image_url = serializers.SerializerMethodField("get_image_url")
def get_image_url(self, obj):
@@ -50,31 +56,31 @@ def get_image_url(self, obj):
return image.url
class Meta:
- model = SubletImage
+ model = ItemImage
fields = ["id", "image_url"]
-# complex sublet serializer for use in C/U/D + getting info about a singular sublet
-class SubletSerializer(serializers.ModelSerializer):
- # amenities = AmenitySerializer(many=True, required=False)
- # images = SubletImageURLSerializer(many=True, required=False)
- amenities = serializers.PrimaryKeyRelatedField(
- many=True, queryset=Amenity.objects.all(), required=False
+# complex item serializer for use in C/U/D + getting info about a singular tag
+class ItemSerializer(serializers.ModelSerializer):
+ # amenities = ItemSerializer(many=True, required=False)
+ # images = ItemImageURLSerializer(many=True, required=False)
+ tags = serializers.PrimaryKeyRelatedField(
+ many=True, queryset=Tag.objects.all(), required=False
)
class Meta:
- model = Sublet
+ model = Item
read_only_fields = [
"id",
"created_at",
- "subletter",
- "sublettees",
+ "seller",
+ "buyer",
# "images"
]
fields = [
"id",
- "subletter",
- "amenities",
+ "seller",
+ "tags",
"title",
"address",
"beds",
@@ -89,7 +95,7 @@ class Meta:
# "images",
# images are now created/deleted through a separate endpoint (see urls.py)
# this serializer isn't used for getting,
- # but gets on sublets will include ids/urls for images
+ # but gets on tags will include ids/urls for images
]
def validate_title(self, value):
@@ -106,47 +112,47 @@ def contains_profanity(self, text):
return predict([text])[0]
def create(self, validated_data):
- validated_data["subletter"] = self.context["request"].user
+ validated_data["seller"] = self.context["request"].user
instance = super().create(validated_data)
instance.save()
return instance
# delete_images is a list of image ids to delete
def update(self, instance, validated_data):
- # Check if the user is the subletter before allowing the update
+ # Check if the user is the seller before allowing the update
if (
- self.context["request"].user == instance.subletter
+ self.context["request"].user == instance.seller
or self.context["request"].user.is_superuser
):
instance = super().update(instance, validated_data)
instance.save()
return instance
else:
- raise serializers.ValidationError("You do not have permission to update this sublet.")
+ raise serializers.ValidationError("You do not have permission to update this item.")
def destroy(self, instance):
- # Check if the user is the subletter before allowing the delete
+ # Check if the user is the seller before allowing the delete
if (
- self.context["request"].user == instance.subletter
+ self.context["request"].user == instance.seller
or self.context["request"].user.is_superuser
):
instance.delete()
else:
- raise serializers.ValidationError("You do not have permission to delete this sublet.")
+ raise serializers.ValidationError("You do not have permission to delete this item.")
-class SubletSerializerRead(serializers.ModelSerializer):
+class ItemSerializerRead(serializers.ModelSerializer):
amenities = serializers.PrimaryKeyRelatedField(
- many=True, queryset=Amenity.objects.all(), required=False
+ many=True, queryset=Tag.objects.all(), required=False
)
- images = SubletImageURLSerializer(many=True, required=False)
+ images = ItemImageURLSerializer(many=True, required=False)
class Meta:
- model = Sublet
- read_only_fields = ["id", "created_at", "subletter", "sublettees"]
+ model = Item
+ read_only_fields = ["id", "created_at", "seller", "buyer"]
fields = [
"id",
- "subletter",
+ "seller",
"amenities",
"title",
"address",
@@ -163,18 +169,18 @@ class Meta:
]
-# simple sublet serializer for use when pulling all serializers/etc
-class SubletSerializerSimple(serializers.ModelSerializer):
+# simple tag serializer for use when pulling all serializers/etc
+class ItemSerializerSimple(serializers.ModelSerializer):
amenities = serializers.PrimaryKeyRelatedField(
- many=True, queryset=Amenity.objects.all(), required=False
+ many=True, queryset=Tag.objects.all(), required=False
)
- images = SubletImageURLSerializer(many=True, required=False)
+ images = ItemImageURLSerializer(many=True, required=False)
class Meta:
- model = Sublet
+ model = Item
fields = [
"id",
- "subletter",
+ "seller",
"amenities",
"title",
"address",
@@ -186,4 +192,4 @@ class Meta:
"end_date",
"images",
]
- read_only_fields = ["id", "subletter"]
+ read_only_fields = ["id", "seller"]
diff --git a/backend/market/urls.py b/backend/market/urls.py
index 14efe102..4149f863 100644
--- a/backend/market/urls.py
+++ b/backend/market/urls.py
@@ -2,7 +2,7 @@
from rest_framework import routers
from market.views import (
- Amenities,
+ Tags,
CreateImages,
DeleteImage,
Favorites,
@@ -13,37 +13,37 @@
)
-app_name = "sublet"
+app_name = "market"
router = routers.DefaultRouter()
router.register(r"properties", Properties, basename="properties")
additional_urls = [
# List of all amenities
- path("amenities/", Amenities.as_view(), name="amenities"),
+ path("tags/", Tags.as_view(), name="tags"),
# All favorites for user
path("favorites/", UserFavorites.as_view(), name="user-favorites"),
# All offers made by user
path("offers/", UserOffers.as_view(), name="user-offers"),
# Favorites
- # post: add a sublet to the user's favorites
- # delete: remove a sublet from the user's favorites
+ # post: add an item to the user's favorites
+ # delete: remove an item from the user's favorites
path(
- "properties//favorites/",
+ "properties//favorites/",
Favorites.as_view({"post": "create", "delete": "destroy"}),
),
# Offers
- # get: list all offers for a sublet
- # post: create an offer for a sublet
- # delete: delete an offer for a sublet
+ # get: list all offers for an item
+ # post: create an offer for an item
+ # delete: delete an offer for an item
path(
- "properties//offers/",
+ "properties//offers/",
Offers.as_view({"get": "list", "post": "create", "delete": "destroy"}),
),
# Image Creation
- path("properties//images/", CreateImages.as_view()),
+ path("properties//images/", CreateImages.as_view()),
# Image Deletion
- path("properties/images//", DeleteImage.as_view()),
+ path("properties/images//", DeleteImage.as_view()),
]
urlpatterns = router.urls + additional_urls
diff --git a/backend/market/views.py b/backend/market/views.py
index 6d64bbd4..f8df8ec7 100644
--- a/backend/market/views.py
+++ b/backend/market/views.py
@@ -7,21 +7,23 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
-from market.models import Amenity, Offer, Sublet, SubletImage
+from market.models import Tag, Category, Offer, Item, Sublet, ItemImage
from market.permissions import (
IsSuperUser,
OfferOwnerPermission,
- SubletImageOwnerPermission,
- SubletOwnerPermission,
+ ItemImageOwnerPermission,
+ ItemOwnerPermission,
)
from market.serializers import (
- AmenitySerializer,
+ TagSerializer,
OfferSerializer,
- SubletImageSerializer,
- SubletImageURLSerializer,
- SubletSerializer,
- SubletSerializerRead,
- SubletSerializerSimple,
+ CategorySerializer,
+ ItemImageSerializer,
+ ItemImageURLSerializer,
+ ItemSerializer,
+ ItemSerializerRead,
+ ItemSerializerRead,
+ ItemSerializerSimple,
)
from pennmobile.analytics import Metric, record_analytics
@@ -29,9 +31,9 @@
User = get_user_model()
-class Amenities(generics.ListAPIView):
- serializer_class = AmenitySerializer
- queryset = Amenity.objects.all()
+class Tags(generics.ListAPIView):
+ serializer_class = TagSerializer
+ queryset = Tag.objects.all()
def get(self, request, *args, **kwargs):
temp = super().get(self, request, *args, **kwargs).data
@@ -40,12 +42,12 @@ def get(self, request, *args, **kwargs):
class UserFavorites(generics.ListAPIView):
- serializer_class = SubletSerializerSimple
+ serializer_class = ItemSerializerSimple
permission_classes = [IsAuthenticated]
def get_queryset(self):
user = self.request.user
- return user.sublets_favorited
+ return user.items_favorited
class UserOffers(generics.ListAPIView):
@@ -60,33 +62,33 @@ def get_queryset(self):
class Properties(viewsets.ModelViewSet):
"""
list:
- Returns a list of Sublets that match query parameters (e.g., amenities) and belong to the user.
+ Returns a list of Items that match query parameters (e.g., amenities) and belong to the user.
create:
- Create a Sublet.
+ Create an Item.
partial_update:
- Update certain fields in the Sublet. Only the owner can edit it.
+ Update certain fields in the Item. Only the owner can edit it.
destroy:
- Delete a Sublet.
+ Delete an Item.
"""
- permission_classes = [SubletOwnerPermission | IsSuperUser]
+ permission_classes = [ItemOwnerPermission | IsSuperUser]
def get_serializer_class(self):
- return SubletSerializerRead if self.action == "retrieve" else SubletSerializer
+ return ItemSerializerRead if self.action == "retrieve" else ItemSerializer
def get_queryset(self):
- return Sublet.objects.all()
+ return Item.objects.all()
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) # Check if the data is valid
- instance = serializer.save() # Create the Sublet
- instance_serializer = SubletSerializerRead(instance=instance, context={"request": request})
+ instance = serializer.save() # Create the Item
+ instance_serializer = ItemSerializerRead(instance=instance, context={"request": request})
- record_analytics(Metric.SUBLET_CREATED, request.user.username)
+ #record_analytics(Metric.SUBLET_CREATED, request.user.username)
return Response(instance_serializer.data, status=status.HTTP_201_CREATED)
@@ -105,7 +107,7 @@ def update(self, request, *args, **kwargs):
# and then re-prefetch related objects
instance._prefetched_objects_cache = {}
prefetch_related_objects([instance], *queryset._prefetch_related_lookups)
- return Response(SubletSerializerRead(instance=instance).data)
+ return Response(ItemSerializerRead(instance=instance).data)
# This is currently redundant but will leave for use when implementing image creation
# def create(self, request, *args, **kwargs):
@@ -121,19 +123,19 @@ def update(self, request, *args, **kwargs):
# serializer = self.get_serializer(data=new_data)
# serializer.is_valid(raise_exception=True)
- # sublet = serializer.save()
- # sublet.amenities.set(amenities)
- # sublet.save()
+ # item = serializer.save()
+ # item.amenities.set(amenities)
+ # item.save()
# return Response(serializer.data, status=status.HTTP_201_CREATED)
def list(self, request, *args, **kwargs):
- """Returns a list of Sublets that match query parameters and user ownership."""
+ """Returns a list of Items that match query parameters and user ownership."""
# Get query parameters from request (e.g., amenities, user_owned)
params = request.query_params
amenities = params.getlist("amenities")
title = params.get("title")
address = params.get("address")
- subletter = params.get("subletter", "false") # Defaults to False if not specified
+ seller = params.get("seller", "false") # Defaults to False if not specified
starts_before = params.get("starts_before", None)
starts_after = params.get("starts_after", None)
ends_before = params.get("ends_before", None)
@@ -148,8 +150,8 @@ def list(self, request, *args, **kwargs):
# Apply filters based on query parameters
- if subletter.lower() == "true":
- queryset = queryset.filter(subletter=request.user)
+ if seller.lower() == "true":
+ queryset = queryset.filter(seller=request.user)
else:
queryset = queryset.filter(expires_at__gte=timezone.now())
if title:
@@ -178,46 +180,46 @@ def list(self, request, *args, **kwargs):
if baths:
queryset = queryset.filter(baths=baths)
- record_analytics(Metric.SUBLET_BROWSE, request.user.username)
+ #record_analytics(Metric.SUBLET_BROWSE, request.user.username)
# Serialize and return the queryset
- serializer = SubletSerializerSimple(queryset, many=True)
+ serializer = ItemSerializerSimple(queryset, many=True)
return Response(serializer.data)
class CreateImages(generics.CreateAPIView):
- serializer_class = SubletImageSerializer
+ serializer_class = ItemImageSerializer
http_method_names = ["post"]
- permission_classes = [SubletImageOwnerPermission | IsSuperUser]
+ permission_classes = [ItemImageOwnerPermission | IsSuperUser]
parser_classes = (
MultiPartParser,
FormParser,
)
def get_queryset(self, *args, **kwargs):
- sublet = get_object_or_404(Sublet, id=int(self.kwargs["sublet_id"]))
- return SubletImage.objects.filter(sublet=sublet)
+ item = get_object_or_404(Item, id=int(self.kwargs["item_id"]))
+ return ItemImage.objects.filter(item=item)
# takes an image multipart form data and creates a new image object
def post(self, request, *args, **kwargs):
images = request.data.getlist("images")
- sublet_id = int(self.kwargs["sublet_id"])
- self.get_queryset() # check if sublet exists
+ item_id = int(self.kwargs["item_id"])
+ self.get_queryset() # check if item exists
img_serializers = []
for img in images:
- img_serializer = self.get_serializer(data={"sublet": sublet_id, "image": img})
+ img_serializer = self.get_serializer(data={"item": item_id, "image": img})
img_serializer.is_valid(raise_exception=True)
img_serializers.append(img_serializer)
instances = [img_serializer.save() for img_serializer in img_serializers]
- data = [SubletImageURLSerializer(instance=instance).data for instance in instances]
+ data = [ItemImageURLSerializer(instance=instance).data for instance in instances]
return Response(data, status=status.HTTP_201_CREATED)
class DeleteImage(generics.DestroyAPIView):
- serializer_class = SubletImageSerializer
+ serializer_class = ItemImageSerializer
http_method_names = ["delete"]
- permission_classes = [SubletImageOwnerPermission | IsSuperUser]
- queryset = SubletImage.objects.all()
+ permission_classes = [ItemImageOwnerPermission | IsSuperUser]
+ queryset = ItemImage.objects.all()
def destroy(self, request, *args, **kwargs):
queryset = self.get_queryset()
@@ -230,50 +232,50 @@ def destroy(self, request, *args, **kwargs):
class Favorites(mixins.DestroyModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
- serializer_class = SubletSerializer
+ serializer_class = ItemSerializer
http_method_names = ["post", "delete"]
permission_classes = [IsAuthenticated | IsSuperUser]
def get_queryset(self):
user = self.request.user
- return user.sublets_favorited
+ return user.items_favorited
def create(self, request, *args, **kwargs):
- sublet_id = int(self.kwargs["sublet_id"])
+ item_id = int(self.kwargs["item_id"])
queryset = self.get_queryset()
- if queryset.filter(id=sublet_id).exists():
+ if queryset.filter(id=item_id).exists():
raise exceptions.NotAcceptable("Favorite already exists")
- sublet = get_object_or_404(Sublet, id=sublet_id)
- self.get_queryset().add(sublet)
+ item = get_object_or_404(Item, id=item_id)
+ self.get_queryset().add(item)
- record_analytics(Metric.SUBLET_FAVORITED, request.user.username)
+ #record_analytics(Metric.SUBLET_FAVORITED, request.user.username)
return Response(status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
queryset = self.get_queryset()
- sublet = get_object_or_404(queryset, pk=int(self.kwargs["sublet_id"]))
- self.get_queryset().remove(sublet)
+ item = get_object_or_404(queryset, pk=int(self.kwargs["item_id"]))
+ self.get_queryset().remove(item)
return Response(status=status.HTTP_204_NO_CONTENT)
class Offers(viewsets.ModelViewSet):
"""
list:
- Returns a list of all offers for the sublet matching the provided ID.
+ Returns a list of all offers for the item matching the provided ID.
create:
- Create an offer on the sublet matching the provided ID.
+ Create an offer on the item matching the provided ID.
destroy:
- Delete the offer between the user and the sublet matching the ID.
+ Delete the offer between the user and the item matching the ID.
"""
permission_classes = [OfferOwnerPermission | IsSuperUser]
serializer_class = OfferSerializer
def get_queryset(self):
- return Offer.objects.filter(sublet_id=int(self.kwargs["sublet_id"])).order_by(
+ return Offer.objects.filter(item_id=int(self.kwargs["item_id"])).order_by(
"created_date"
)
@@ -282,19 +284,19 @@ def create(self, request, *args, **kwargs):
request.POST._mutable = True
if self.get_queryset().filter(user=self.request.user).exists():
raise exceptions.NotAcceptable("Offer already exists")
- data["sublet"] = int(self.kwargs["sublet_id"])
+ data["item"] = int(self.kwargs["item_id"])
data["user"] = self.request.user.id
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
- record_analytics(Metric.SUBLET_OFFER, request.user.username)
+ #record_analytics(Metric.SUBLET_OFFER, request.user.username)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
queryset = self.get_queryset()
- filter = {"user": self.request.user.id, "sublet": int(self.kwargs["sublet_id"])}
+ filter = {"user": self.request.user.id, "item": int(self.kwargs["item_id"])}
obj = get_object_or_404(queryset, **filter)
# checking permissions here is kind of redundant
self.check_object_permissions(self.request, obj)
@@ -302,5 +304,5 @@ def destroy(self, request, *args, **kwargs):
return Response(status=status.HTTP_204_NO_CONTENT)
def list(self, request, *args, **kwargs):
- self.check_object_permissions(request, Sublet.objects.get(pk=int(self.kwargs["sublet_id"])))
+ self.check_object_permissions(request, Item.objects.get(pk=int(self.kwargs["item_id"])))
return super().list(request, *args, **kwargs)
diff --git a/backend/pennmobile/settings/base.py b/backend/pennmobile/settings/base.py
index c54b3e21..4d73e450 100644
--- a/backend/pennmobile/settings/base.py
+++ b/backend/pennmobile/settings/base.py
@@ -53,6 +53,7 @@
"options.apps.OptionsConfig",
"sublet",
"phonenumber_field",
+ "market",
]
MIDDLEWARE = [
diff --git a/backend/pennmobile/urls.py b/backend/pennmobile/urls.py
index 5e94960e..3387caf2 100644
--- a/backend/pennmobile/urls.py
+++ b/backend/pennmobile/urls.py
@@ -27,6 +27,7 @@
path("dining/", include("dining.urls")),
path("penndata/", include("penndata.urls")),
path("sublet/", include("sublet.urls")),
+ path("market/", include("market.urls")),
]
urlpatterns = [