winofy-backend/apps/locations/models.py
Ali Asadi 52adc732fa Initial Winofy backend: marketplace core (no payment integration)
Django 6 + DRF resource server against the Gooyal accounts OAuth2 service,
matching the Winsoo ecosystem's conventions. Covers locations, stores,
catalog, cart, checkout/orders (with the multi-store-cart split and the
status stepper), reviews, and notifications, plus a demo-data seed command.

Payment integration (wallet debits, online gateway, seller payouts) is
intentionally left out here — see feature/payment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 14:03:15 +03:30

72 lines
2.6 KiB
Python

from django.conf import settings
from django.contrib.gis.db import models as gis_models
from django.db import models
from utils.models import BaseModel
class City(BaseModel):
name = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
is_active = models.BooleanField(default=True)
class Meta:
ordering = ['name']
verbose_name = 'شهر'
verbose_name_plural = 'شهرها'
def __str__(self):
return self.name
class Neighborhood(BaseModel):
city = models.ForeignKey(City, on_delete=models.CASCADE, related_name='neighborhoods')
name = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
center = gis_models.PointField(geography=True, null=True, blank=True)
is_active = models.BooleanField(default=True)
class Meta:
ordering = ['name']
unique_together = ('city', 'slug')
verbose_name = 'محله'
verbose_name_plural = 'محله‌ها'
def __str__(self):
return f'{self.name} ({self.city.name})'
class Address(BaseModel):
class Label(models.TextChoices):
HOME = 'home', 'خانه'
WORK = 'work', 'محل کار'
OTHER = 'other', 'سایر'
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='addresses')
city = models.ForeignKey(City, on_delete=models.PROTECT, related_name='addresses')
neighborhood = models.ForeignKey(
Neighborhood, on_delete=models.PROTECT, related_name='addresses', null=True, blank=True,
)
label = models.CharField(max_length=10, choices=Label.choices, default=Label.HOME)
title = models.CharField(max_length=100, blank=True)
full_address = models.TextField()
plaque = models.CharField(max_length=20, blank=True)
floor = models.CharField(max_length=20, blank=True)
unit = models.CharField(max_length=20, blank=True)
recipient_name = models.CharField(max_length=150)
recipient_phone = models.CharField(max_length=20)
location = gis_models.PointField(geography=True, null=True, blank=True)
is_default = models.BooleanField(default=False)
class Meta:
ordering = ['-is_default', '-created_at']
verbose_name = 'آدرس'
verbose_name_plural = 'آدرس‌ها'
def __str__(self):
return f'{self.get_label_display()} - {self.full_address[:30]}'
def save(self, *args, **kwargs):
if self.is_default:
Address.objects.filter(user=self.user).exclude(pk=self.pk).update(is_default=False)
super().save(*args, **kwargs)