Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
291b7e4825 |
51 changed files with 46 additions and 804 deletions
217
.gitignore
vendored
217
.gitignore
vendored
|
|
@ -1,217 +0,0 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[codz]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
# Pipfile.lock
|
||||
|
||||
# UV
|
||||
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# uv.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
# poetry.lock
|
||||
# poetry.toml
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
||||
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
||||
# pdm.lock
|
||||
# pdm.toml
|
||||
.pdm-python
|
||||
.pdm-build/
|
||||
|
||||
# pixi
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
||||
# pixi.lock
|
||||
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
||||
# in the .venv directory. It is recommended not to include this directory in version control.
|
||||
.pixi
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# Redis
|
||||
*.rdb
|
||||
*.aof
|
||||
*.pid
|
||||
|
||||
# RabbitMQ
|
||||
mnesia/
|
||||
rabbitmq/
|
||||
rabbitmq-data/
|
||||
|
||||
# ActiveMQ
|
||||
activemq-data/
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.envrc
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
# .idea/
|
||||
|
||||
# Abstra
|
||||
# Abstra is an AI-powered process automation framework.
|
||||
# Ignore directories containing user credentials, local state, and settings.
|
||||
# Learn more at https://abstra.io/docs
|
||||
.abstra/
|
||||
|
||||
# Visual Studio Code
|
||||
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
||||
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||
# you could uncomment the following to ignore the entire vscode folder
|
||||
# .vscode/
|
||||
|
||||
# Ruff stuff:
|
||||
.ruff_cache/
|
||||
|
||||
# PyPI configuration file
|
||||
.pypirc
|
||||
|
||||
# Marimo
|
||||
marimo/_static/
|
||||
marimo/_lsp/
|
||||
__marimo__/
|
||||
|
||||
# Streamlit
|
||||
.streamlit/secrets.toml
|
||||
config*
|
||||
BIN
api/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
api/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
BIN
api/__pycache__/admin.cpython-314.pyc
Normal file
BIN
api/__pycache__/admin.cpython-314.pyc
Normal file
Binary file not shown.
BIN
api/__pycache__/apps.cpython-314.pyc
Normal file
BIN
api/__pycache__/apps.cpython-314.pyc
Normal file
Binary file not shown.
BIN
api/__pycache__/models.cpython-314.pyc
Normal file
BIN
api/__pycache__/models.cpython-314.pyc
Normal file
Binary file not shown.
BIN
api/migrations/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
api/migrations/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
3
api/models.py
Normal file
3
api/models.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
from rest_framework import serializers
|
||||
from web.models.category import Category
|
||||
|
||||
|
||||
class CategorySerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Category
|
||||
fields = '__all__'
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
from rest_framework import serializers
|
||||
from django.forms.models import model_to_dict
|
||||
from web.models.event import Event
|
||||
from web.models.event_category import EventCategory
|
||||
from web.models.event_tag import EventTag
|
||||
|
||||
|
||||
class EventSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Event
|
||||
fields = '__all__'
|
||||
|
||||
def to_representation(self, instance):
|
||||
representation = super().to_representation(instance)
|
||||
|
||||
event_categories = EventCategory.objects.filter(event=instance).filter(active=True).all()
|
||||
event_tags = EventTag.objects.filter(event=instance).filter(active=True).all()
|
||||
representation['location'] = {
|
||||
'lng': instance.coordinates.x if instance.coordinates else None,
|
||||
'lat': instance.coordinates.y if instance.coordinates else None
|
||||
}
|
||||
|
||||
representation['categories'] = self._parse_categories(event_categories)
|
||||
representation['tags'] = self._parse_tags(event_tags)
|
||||
return representation
|
||||
|
||||
def _parse_categories(self, event_categories):
|
||||
categories = []
|
||||
if event_categories.exists():
|
||||
for event_category in event_categories:
|
||||
categories.append({
|
||||
'id': event_category.category.id,
|
||||
'name': event_category.category.name,
|
||||
'description': event_category.category.description,
|
||||
'_meta': model_to_dict(event_category)
|
||||
})
|
||||
return categories
|
||||
|
||||
def _parse_tags(self, event_tags):
|
||||
tags = []
|
||||
if event_tags.exists():
|
||||
for event_tag in event_tags:
|
||||
tags.append({
|
||||
'id': event_tag.tag.id,
|
||||
'name': event_tag.tag.name,
|
||||
'_meta': model_to_dict(event_tag)
|
||||
})
|
||||
return tags
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from web.models.event_category import EventCategory
|
||||
|
||||
|
||||
class EventCategorySerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = EventCategory
|
||||
fields = "all"
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from web.models.event_tag import EventTag
|
||||
|
||||
|
||||
class EventTagSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = EventTag
|
||||
fields = "all"
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
from rest_framework import serializers
|
||||
from web.models.tag import Tag
|
||||
|
||||
|
||||
class TagSerializer(serializers.ModelSerializer):
|
||||
# to_representation(self, instance) if needed
|
||||
# fk = Serializer()
|
||||
|
||||
class Meta:
|
||||
model = Tag
|
||||
fields = '__all__'
|
||||
|
||||
3
api/views.py
Normal file
3
api/views.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
|
||||
|
||||
class BaseView(APIView):
|
||||
SERIALIZER = None
|
||||
|
||||
def _build_response(self, data):
|
||||
model_serializer = self.SERIALIZER(data)
|
||||
|
||||
response = Response()
|
||||
response.data = model_serializer.data
|
||||
return response
|
||||
|
||||
def _build_multi_response(self, data):
|
||||
serialized_data = []
|
||||
for d in data:
|
||||
serializer = self.SERIALIZER(d)
|
||||
serialized_data.append(serializer.data)
|
||||
|
||||
response = Response()
|
||||
response.data = serialized_data
|
||||
return response
|
||||
|
||||
def error_response(self, status_code, description):
|
||||
response = Response()
|
||||
response.status_code = status_code
|
||||
response.data = {"error": description}
|
||||
return response
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import json
|
||||
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from api.serializers.category import CategorySerializer
|
||||
from api.views.base import BaseView
|
||||
from web.models.category import Category
|
||||
|
||||
|
||||
class CategoryView(BaseView):
|
||||
SERIALIZER = CategorySerializer
|
||||
|
||||
def get(self, request, category_id=None):
|
||||
if category_id:
|
||||
category = get_object_or_404(Category, pk=category_id)
|
||||
return self._build_response(category)
|
||||
else:
|
||||
categories = Category.objects.filter(active=True).all()
|
||||
return self._build_multi_response(categories)
|
||||
|
||||
def post(self, request):
|
||||
data = json.loads(request.body)
|
||||
category = Category(
|
||||
name=data.get('name'),
|
||||
description=data.get('description')
|
||||
)
|
||||
|
||||
category.save()
|
||||
return self._build_response(category)
|
||||
|
||||
def put(self, request, category_id):
|
||||
data = json.loads(request.body)
|
||||
|
||||
category = get_object_or_404(Category, pk=category_id)
|
||||
|
||||
category.name = data.get('name', category.name)
|
||||
category.description = data.get('description', category.description)
|
||||
return self._build_response(category)
|
||||
|
||||
def delete(self, request, category_id):
|
||||
category = get_object_or_404(Category, pk=category_id)
|
||||
category.active = False
|
||||
category.save()
|
||||
return self._build_response(category)
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
import json
|
||||
|
||||
from django.contrib.gis.geos import Point
|
||||
from django.contrib.gis.measure import D
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from api.serializers.event import EventSerializer
|
||||
from api.views.base import BaseView
|
||||
from web.models.category import Category
|
||||
from web.models.event_category import EventCategory
|
||||
from web.models.event import Event
|
||||
from web.models.tag import Tag
|
||||
from web.models.event_tag import EventTag
|
||||
|
||||
|
||||
class EventView(BaseView):
|
||||
SERIALIZER = EventSerializer
|
||||
|
||||
def get(self, request, event_id=None):
|
||||
if event_id:
|
||||
event = get_object_or_404(Event, pk=event_id, active=True)
|
||||
return self._build_response(event)
|
||||
else:
|
||||
return self._get_events_by_radius(request)
|
||||
|
||||
def _get_events_by_radius(self, request):
|
||||
lat = request.GET.get('lat')
|
||||
lng = request.GET.get('lng')
|
||||
r = request.GET.get('r')
|
||||
|
||||
if all([lat, lng, r]):
|
||||
try:
|
||||
user_location = Point(float(lng), float(lat), srid=4326)
|
||||
events = Event.objects.filter(active=True).filter(coordinates__dwithin=(user_location, D(mi=float(r)))).all()
|
||||
return self._build_multi_response(events)
|
||||
except ValueError:
|
||||
return self.error_response(400, 'Invalid coordinates or radius format')
|
||||
else:
|
||||
return self.error_response(400, 'Must include lat, lng, and r in query string')
|
||||
|
||||
@transaction.atomic
|
||||
def post(self, request):
|
||||
data = json.loads(request.body)
|
||||
|
||||
location = data.get('location', {})
|
||||
coordinates = Point(location.get("lng"), location.get("lat"), srid=4326)
|
||||
|
||||
event = Event(
|
||||
name=data.get('name'),
|
||||
description=data.get('description'),
|
||||
url=data.get('url'),
|
||||
address=data.get('address'),
|
||||
status=data.get('status'),
|
||||
price=data.get('price'),
|
||||
require_rsvp=data.get('require_rsvp'),
|
||||
start_time=data.get('start_time'),
|
||||
end_time=data.get('end_time'),
|
||||
rain_date=data.get('rain_date'),
|
||||
email=data.get('email'),
|
||||
phone_number=data.get('phone_number'),
|
||||
coordinates=coordinates,
|
||||
)
|
||||
|
||||
event.save()
|
||||
|
||||
categories = data.get('categories', [])
|
||||
self._create_event_categories(categories, event)
|
||||
|
||||
tag_names = data.get('tags', [])
|
||||
self._create_event_tags(tag_names, event)
|
||||
|
||||
return self._build_response(event)
|
||||
|
||||
def _create_event_categories(self, categories, event):
|
||||
event_categories = []
|
||||
for category_id in categories:
|
||||
category = get_object_or_404(Category, pk=category_id)
|
||||
event_category = EventCategory(
|
||||
event=event,
|
||||
category=category
|
||||
)
|
||||
|
||||
event_categories.append(event_category)
|
||||
EventCategory.objects.bulk_create(event_categories)
|
||||
|
||||
def _create_event_tags(self, tag_names, event):
|
||||
event_tags = []
|
||||
for tag_name in tag_names:
|
||||
tag, created = Tag.objects.get_or_create(name=tag_name)
|
||||
|
||||
event_tag = EventTag(
|
||||
tag=tag,
|
||||
event=event
|
||||
)
|
||||
|
||||
event_tags.append(event_tag)
|
||||
EventTag.objects.bulk_create(event_tags)
|
||||
|
||||
@transaction.atomic
|
||||
def put(self, request, event_id):
|
||||
data = json.loads(request.body)
|
||||
|
||||
event = get_object_or_404(Event, pk=event_id)
|
||||
|
||||
location = data.get('location', {})
|
||||
if location:
|
||||
coordinates = Point(location.get("lng"), location.get("lat"), srid=4326)
|
||||
event.coordinates = coordinates
|
||||
|
||||
event.name = data.get('name', event.name)
|
||||
event.description = data.get('description', event.description)
|
||||
event.url = data.get('url', event.url)
|
||||
event.address = data.get('address', event.address)
|
||||
event.status = data.get('status', event.status)
|
||||
event.price = data.get('price', event.price)
|
||||
event.require_rsvp = data.get('require_rsvp', event.require_rsvp)
|
||||
event.start_time = data.get('start_time', event.start_time)
|
||||
event.end_time = data.get('end_time', event.end_time)
|
||||
event.rain_date = data.get('rain_date', event.rain_date)
|
||||
event.email = data.get('email', event.email)
|
||||
event.phone_number = data.get('phone_number', event.phone_number)
|
||||
|
||||
categories = data.get('categories', [])
|
||||
self._update_event_categories(categories, event)
|
||||
|
||||
tag_names = data.get('tags', [])
|
||||
self._update_event_tags(tag_names, event)
|
||||
|
||||
event.save()
|
||||
self._build_response(event)
|
||||
|
||||
def _update_event_categories(self, categories, event):
|
||||
if categories:
|
||||
current_event_categories = EventCategory.objects.filter(event=event).filter(active=True).all()
|
||||
current_event_category_map = {ec.category.id: ec for ec in current_event_categories}
|
||||
|
||||
for current_event_category in current_event_categories:
|
||||
if current_event_category.category.id not in categories:
|
||||
current_event_category.active = False
|
||||
current_event_category.save()
|
||||
|
||||
new_event_categories = []
|
||||
for category_id in categories:
|
||||
category = get_object_or_404(Category, pk=category_id)
|
||||
if category not in current_event_category_map:
|
||||
event_category = EventCategory(
|
||||
category=category,
|
||||
event=event
|
||||
)
|
||||
|
||||
new_event_categories.append(event_category)
|
||||
|
||||
if new_event_categories:
|
||||
EventCategory.objects.bulk_create(new_event_categories)
|
||||
|
||||
def _update_event_tags(self, tag_names, event):
|
||||
if tag_names:
|
||||
current_event_tags = EventTag.objects.filter(event=event).filter(active=True).all()
|
||||
current_event_tag_names = [x.name for x in current_event_tags]
|
||||
|
||||
for current_event_tag in current_event_tags:
|
||||
if current_event_tag.tag.name not in tag_names:
|
||||
current_event_tag.active = False
|
||||
current_event_tag.save()
|
||||
|
||||
new_event_tags = []
|
||||
for tag_name in tag_names:
|
||||
if tag_name not in current_event_tag_names:
|
||||
tag, created = Tag.objects.get_or_create(name=tag_name)
|
||||
|
||||
event_tag = EventTag(
|
||||
tag=tag,
|
||||
event=event
|
||||
)
|
||||
|
||||
new_event_tags.append(event_tag)
|
||||
|
||||
if new_event_tags:
|
||||
EventTag.objects.bulk_create(new_event_tags)
|
||||
|
||||
def delete(self, request, event_id):
|
||||
event = get_object_or_404(Event, pk=event_id)
|
||||
event.active = False
|
||||
event.save()
|
||||
return self._build_response(event)
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
import json
|
||||
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from api.serializers.tag import TagSerializer
|
||||
from api.views.base import BaseView
|
||||
from web.models.tag import Tag
|
||||
|
||||
|
||||
class TagView(BaseView):
|
||||
SERIALIZER = TagSerializer
|
||||
|
||||
def get(self, request, tag_id=None):
|
||||
if tag_id:
|
||||
tag = get_object_or_404(Tag, pk=tag_id)
|
||||
return self._build_response(tag)
|
||||
else:
|
||||
tags = Tag.objects.filter(active=True).all()
|
||||
return self._build_multi_response(tags)
|
||||
|
||||
def post(self, request):
|
||||
data = json.loads(request.body)
|
||||
tag = Tag(
|
||||
name=data.get('name'),
|
||||
)
|
||||
|
||||
tag.save()
|
||||
return self._build_response(tag)
|
||||
|
||||
def put(self, request, tag_id):
|
||||
data = json.loads(request.body)
|
||||
|
||||
tag = get_object_or_404(Tag, pk=tag_id)
|
||||
tag.name = data.get('name', tag.name)
|
||||
tag.save()
|
||||
self._build_response(tag)
|
||||
|
||||
def delete(self, request, tag_id):
|
||||
tag = get_object_or_404(Tag, pk=tag_id)
|
||||
tag.active = False
|
||||
tag.save()
|
||||
return self._build_response(tag)
|
||||
BIN
db.sqlite3
Normal file
BIN
db.sqlite3
Normal file
Binary file not shown.
BIN
localist/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
localist/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
BIN
localist/__pycache__/settings.cpython-314.pyc
Normal file
BIN
localist/__pycache__/settings.cpython-314.pyc
Normal file
Binary file not shown.
BIN
localist/__pycache__/urls.cpython-314.pyc
Normal file
BIN
localist/__pycache__/urls.cpython-314.pyc
Normal file
Binary file not shown.
BIN
localist/__pycache__/wsgi.cpython-314.pyc
Normal file
BIN
localist/__pycache__/wsgi.cpython-314.pyc
Normal file
Binary file not shown.
|
|
@ -1,5 +1,16 @@
|
|||
"""
|
||||
Django settings for localist project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 6.0.6.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/6.0/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/6.0/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from config import DB_NAME, DB_USER, DB_HOST, DB_PASSWORD, DB_PORT, SECRET_KEY
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
|
@ -9,7 +20,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||
# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = SECRET_KEY
|
||||
SECRET_KEY = "django-insecure-pek1teheggj8zzvtcntp4-u#s_^yc$&a@3f7wi+u%8)g*2xezw"
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
|
@ -20,23 +31,17 @@ ALLOWED_HOSTS = []
|
|||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"corsheaders",
|
||||
"django.contrib.gis",
|
||||
"leaflet",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"rest_framework",
|
||||
"web",
|
||||
"api",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
"corsheaders.middleware.CorsMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
|
|
@ -71,12 +76,8 @@ WSGI_APPLICATION = "localist.wsgi.application"
|
|||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.contrib.gis.db.backends.postgis",
|
||||
"NAME": DB_NAME,
|
||||
"USER": DB_USER,
|
||||
"PASSWORD": DB_PASSWORD,
|
||||
"HOST": DB_HOST,
|
||||
"PORT": DB_PORT
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "db.sqlite3",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -116,9 +117,3 @@ USE_TZ = True
|
|||
# https://docs.djangoproject.com/en/6.0/howto/static-files/
|
||||
|
||||
STATIC_URL = "static/"
|
||||
|
||||
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
"""
|
||||
URL configuration for localist project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/6.0/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
|
||||
from api.views.event import EventView
|
||||
from api.views.category import CategoryView
|
||||
from api.views.tag import TagView
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/event/<int:event_id>", EventView.as_view(), name="event"),
|
||||
path("api/event", EventView.as_view(), name="event"),
|
||||
path("api/category/<int:category_id>", CategoryView.as_view(), name="category"),
|
||||
path("api/category", CategoryView.as_view(), name="category"),
|
||||
path("api/tag/<int:tag_id>", TagView.as_view(), name="tag"),
|
||||
path("api/tag", TagView.as_view(), name="tag"),
|
||||
]
|
||||
|
|
|
|||
23
manage.py
23
manage.py
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "localist.settings")
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
asgiref==3.11.1
|
||||
certifi==2026.5.20
|
||||
charset-normalizer==3.4.7
|
||||
Django==6.0.6
|
||||
django-cors-headers==4.0.0
|
||||
django-leaflet==0.33.0
|
||||
django-rest-framework==0.1.0
|
||||
djangorestframework==3.17.1
|
||||
idna==3.18
|
||||
psycopg==3.3.4
|
||||
psycopg-binary==3.3.4
|
||||
requests==2.34.2
|
||||
sqlparse==0.5.5
|
||||
urllib3==2.7.0
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import requests
|
||||
|
||||
url = "http://127.0.0.1:8000/api/category"
|
||||
|
||||
data = {
|
||||
"name": "Test Category",
|
||||
"description": "this is a test",
|
||||
}
|
||||
|
||||
resp = requests.post(url, data=data)
|
||||
print(resp.status_code)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import requests
|
||||
|
||||
url = "http://127.0.0.1:8000/api/category/1"
|
||||
|
||||
data = {
|
||||
"name": "diddy cat"
|
||||
}
|
||||
|
||||
resp = requests.put(url, data=data)
|
||||
print(resp.status_code)
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import requests
|
||||
|
||||
url = "http://127.0.0.1:8000/api/event"
|
||||
|
||||
data = {
|
||||
"name": "Test Event 3",
|
||||
"description": "this is a test",
|
||||
"url": "https://www.domdit.com",
|
||||
"address": "31 Fleetwood Dr Hazlet Nj",
|
||||
"status": "scheduled",
|
||||
"price": "10.00",
|
||||
"require_rsvp": False,
|
||||
"start_time": "2026-06-14T01:34:39Z",
|
||||
"end_time": "2026-08-14T01:34:38Z",
|
||||
"rain_date": "2026-06-15T01:34:42Z",
|
||||
"email": "me@domdit.com",
|
||||
"phone_number": "",
|
||||
"categories": [1],
|
||||
"tags": ["tag1", "tag2", "tag4"]
|
||||
|
||||
}
|
||||
|
||||
resp = requests.post(url, json=data)
|
||||
print(resp.status_code)
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import requests
|
||||
|
||||
url = "http://127.0.0.1:8000/api/event/1"
|
||||
|
||||
data = {
|
||||
"name": "diddy freakoff",
|
||||
}
|
||||
|
||||
resp = requests.put(url, data=data)
|
||||
print(resp.status_code)
|
||||
BIN
web/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
web/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/__pycache__/admin.cpython-314.pyc
Normal file
BIN
web/__pycache__/admin.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/__pycache__/apps.cpython-314.pyc
Normal file
BIN
web/__pycache__/apps.cpython-314.pyc
Normal file
Binary file not shown.
|
|
@ -5,7 +5,6 @@ from web.models.event_category import EventCategory, EventCategoryAdmin
|
|||
from web.models.event_tag import EventTag, EventTagAdmin
|
||||
from web.models.tag import Tag, TagAdmin
|
||||
|
||||
|
||||
admin.site.register(Category, CategoryAdmin)
|
||||
admin.site.register(Event, EventAdmin)
|
||||
admin.site.register(EventCategory, EventCategoryAdmin)
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 6.0.6 on 2026-06-21 00:12
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("web", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="eventcategory",
|
||||
name="category",
|
||||
field=models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="category",
|
||||
to="web.category",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# Generated by Django 6.0.6 on 2026-06-21 17:56
|
||||
|
||||
import django.contrib.gis.db.models.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("web", "0002_alter_eventcategory_category"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="event",
|
||||
name="coordinates",
|
||||
field=django.contrib.gis.db.models.fields.PointField(
|
||||
blank=True, default=None, null=True, srid=4326
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# Generated by Django 6.0.6 on 2026-06-21 19:33
|
||||
|
||||
import django.contrib.gis.db.models.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("web", "0003_event_coordinates"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="event",
|
||||
name="coordinates",
|
||||
field=django.contrib.gis.db.models.fields.PointField(
|
||||
blank=True, default=None, geography=True, null=True, srid=4326
|
||||
),
|
||||
),
|
||||
]
|
||||
BIN
web/migrations/__pycache__/0001_initial.cpython-314.pyc
Normal file
BIN
web/migrations/__pycache__/0001_initial.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/migrations/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
web/migrations/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/models/__pycache__/base.cpython-314.pyc
Normal file
BIN
web/models/__pycache__/base.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/models/__pycache__/category.cpython-314.pyc
Normal file
BIN
web/models/__pycache__/category.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/models/__pycache__/event.cpython-314.pyc
Normal file
BIN
web/models/__pycache__/event.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/models/__pycache__/event_category.cpython-314.pyc
Normal file
BIN
web/models/__pycache__/event_category.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/models/__pycache__/event_tag.cpython-314.pyc
Normal file
BIN
web/models/__pycache__/event_tag.cpython-314.pyc
Normal file
Binary file not shown.
BIN
web/models/__pycache__/tag.cpython-314.pyc
Normal file
BIN
web/models/__pycache__/tag.cpython-314.pyc
Normal file
Binary file not shown.
|
|
@ -1,7 +1,8 @@
|
|||
from django.db import models
|
||||
from django.contrib import admin
|
||||
from leaflet.admin import LeafletGeoAdmin
|
||||
from django.contrib.gis.db import models
|
||||
from web.models.base import BaseModel
|
||||
from enum import StrEnum
|
||||
|
||||
|
||||
|
||||
class Event(BaseModel):
|
||||
|
|
@ -14,7 +15,6 @@ class Event(BaseModel):
|
|||
description = models.TextField()
|
||||
url = models.URLField()
|
||||
address = models.CharField()
|
||||
coordinates = models.PointField(blank=True, default=None, null=True, srid=4326, geography=True)
|
||||
status = models.CharField(max_length=20, choices=Status.choices, default=Status.SCHEDULED)
|
||||
price = models.DecimalField(max_digits=10, default=None, blank=True, decimal_places=2)
|
||||
require_rsvp = models.BooleanField()
|
||||
|
|
@ -30,7 +30,7 @@ class Event(BaseModel):
|
|||
db_table = 'events'
|
||||
|
||||
|
||||
class EventAdmin(LeafletGeoAdmin):
|
||||
class EventAdmin(admin.ModelAdmin):
|
||||
search_fields = (
|
||||
'name',
|
||||
'description',
|
||||
|
|
@ -39,7 +39,6 @@ class EventAdmin(LeafletGeoAdmin):
|
|||
'rain_date',
|
||||
'url',
|
||||
'address',
|
||||
'coordinates',
|
||||
'status',
|
||||
'price',
|
||||
'require_rsvp',
|
||||
|
|
@ -53,7 +52,6 @@ class EventAdmin(LeafletGeoAdmin):
|
|||
'rain_date',
|
||||
'url',
|
||||
'address',
|
||||
'coordinates',
|
||||
'status',
|
||||
'price',
|
||||
'require_rsvp',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from web.models.category import Category
|
|||
|
||||
class EventCategory(BaseModel):
|
||||
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
||||
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category")
|
||||
category = models.ForeignKey(Category, on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
db_table = 'event_categories'
|
||||
|
|
|
|||
3
web/views.py
Normal file
3
web/views.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
Loading…
Reference in a new issue