1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-21 22:09:36 +02:00
AdventureLog/backend/server/adventures/admin.py
Sean Morley 493a13995c
Rename Adventures to Locations (#696)
* Refactor user_id to user in adventures and related models, views, and components

- Updated all instances of user_id to user in the adventures app, including models, serializers, views, and frontend components.
- Adjusted queries and filters to reflect the new user field naming convention.
- Ensured consistency across the codebase for user identification in adventures, collections, notes, and transportation entities.
- Modified frontend components to align with the updated data structure, ensuring proper access control and rendering based on user ownership.

* Refactor adventure-related views and components to use "Location" terminology

- Updated GlobalSearchView to replace AdventureSerializer with LocationSerializer.
- Modified IcsCalendarGeneratorViewSet to use LocationSerializer instead of AdventureSerializer.
- Created new LocationImageViewSet for managing location images, including primary image toggling and image deletion.
- Introduced LocationViewSet for managing locations with enhanced filtering, sorting, and sharing capabilities.
- Updated ReverseGeocodeViewSet to utilize LocationSerializer.
- Added ActivityTypesView to retrieve distinct activity types from locations.
- Refactored user views to replace AdventureSerializer with LocationSerializer.
- Updated frontend components to reflect changes from "adventure" to "location", including AdventureCard, AdventureLink, AdventureModal, and others.
- Adjusted API endpoints in frontend routes to align with new location-based structure.
- Ensured all references to adventures are replaced with locations across the codebase.

* refactor: rename adventures to locations across the application

- Updated localization files to replace adventure-related terms with location-related terms.
- Refactored TypeScript types and variables from Adventure to Location in various routes and components.
- Adjusted UI elements and labels to reflect the change from adventures to locations.
- Ensured all references to adventures in the codebase are consistent with the new location terminology.

* Refactor code structure for improved readability and maintainability

* feat: Implement location details page with server-side loading and deletion functionality

- Added +page.server.ts to handle server-side loading of additional location info.
- Created +page.svelte for displaying location details, including images, visits, and maps.
- Integrated GPX file handling and rendering on the map.
- Updated map route to link to locations instead of adventures.
- Refactored profile and search routes to use LocationCard instead of AdventureCard.

* docs: Update terminology from "Adventure" to "Location" and enhance project overview

* docs: Clarify collection examples in usage documentation

* feat: Enable credentials for GPX file fetch and add CORS_ALLOW_CREDENTIALS setting

* Refactor adventure references to locations across the backend and frontend

- Updated CategoryViewSet to reflect location context instead of adventures.
- Modified ChecklistViewSet to include locations in retrieval logic.
- Changed GlobalSearchView to search for locations instead of adventures.
- Adjusted IcsCalendarGeneratorViewSet to handle locations instead of adventures.
- Refactored LocationImageViewSet to remove unused import.
- Updated LocationViewSet to clarify public access for locations.
- Changed LodgingViewSet to reference locations instead of adventures.
- Modified NoteViewSet to prevent listing all locations.
- Updated RecommendationsViewSet to handle locations in parsing and response.
- Adjusted ReverseGeocodeViewSet to search through user locations.
- Updated StatsViewSet to count locations instead of adventures.
- Changed TagsView to reflect activity types for locations.
- Updated TransportationViewSet to reference locations instead of adventures.
- Added new translations for search results related to locations in multiple languages.
- Updated dashboard and profile pages to reflect location counts instead of adventure counts.
- Adjusted search routes to handle locations instead of adventures.

* Update banner image

* style: Update stats component background and border for improved visibility

* refactor: Rename AdventureCard and AdventureModal to LocationCard and LocationModal for consistency
2025-06-25 11:49:34 -04:00

159 lines
5.6 KiB
Python

import os
from django.contrib import admin
from django.utils.html import mark_safe
from .models import Location, Checklist, ChecklistItem, Collection, Transportation, Note, LocationImage, Visit, Category, Attachment, Lodging
from worldtravel.models import Country, Region, VisitedRegion, City, VisitedCity
from allauth.account.decorators import secure_admin_login
admin.autodiscover()
admin.site.login = secure_admin_login(admin.site.login)
@admin.action(description="Trigger geocoding")
def trigger_geocoding(modeladmin, request, queryset):
count = 0
for location in queryset:
try:
location.save() # Triggers geocoding logic in your model
count += 1
except Exception as e:
modeladmin.message_user(request, f"Error geocoding {location}: {e}", level='error')
modeladmin.message_user(request, f"Geocoding triggered for {count} locations.", level='success')
class LocationAdmin(admin.ModelAdmin):
list_display = ('name', 'get_category', 'get_visit_count', 'user', 'is_public')
list_filter = ( 'user', 'is_public')
search_fields = ('name',)
readonly_fields = ('city', 'region', 'country')
actions = [trigger_geocoding]
def get_category(self, obj):
if obj.category and obj.category.display_name and obj.category.icon:
return obj.category.display_name + ' ' + obj.category.icon
elif obj.category and obj.category.name:
return obj.category.name
else:
return 'No Category'
get_category.short_description = 'Category'
def get_visit_count(self, obj):
return obj.visits.count()
get_visit_count.short_description = 'Visit Count'
class CountryAdmin(admin.ModelAdmin):
list_display = ('name', 'country_code', 'number_of_regions')
list_filter = ('subregion',)
search_fields = ('name', 'country_code')
def number_of_regions(self, obj):
return Region.objects.filter(country=obj).count()
number_of_regions.short_description = 'Number of Regions'
class RegionAdmin(admin.ModelAdmin):
list_display = ('name', 'country', 'number_of_visits')
list_filter = ('country',)
search_fields = ('name', 'country__name')
# list_filter = ('country', 'number_of_visits')
def number_of_visits(self, obj):
return VisitedRegion.objects.filter(region=obj).count()
number_of_visits.short_description = 'Number of Visits'
class CityAdmin(admin.ModelAdmin):
list_display = ('name', 'region', 'country')
list_filter = ('region', 'region__country')
search_fields = ('name', 'region__name', 'region__country__name')
def country(self, obj):
return obj.region.country.name
country.short_description = 'Country'
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from users.models import CustomUser
class CustomUserAdmin(UserAdmin):
model = CustomUser
list_display = ['username', 'is_staff', 'is_active', 'image_display']
readonly_fields = ('uuid',)
search_fields = ('username',)
fieldsets = UserAdmin.fieldsets + (
(None, {'fields': ('profile_pic', 'uuid', 'public_profile', 'disable_password')}),
)
def image_display(self, obj):
if obj.profile_pic:
public_url = os.environ.get('PUBLIC_URL', 'http://127.0.0.1:8000').rstrip('/')
public_url = public_url.replace("'", "")
return mark_safe(f'<img src="{public_url}/media/{obj.profile_pic.name}" width="100px" height="100px"')
else:
return
class LocationImageAdmin(admin.ModelAdmin):
list_display = ('user', 'image_display')
def image_display(self, obj):
if obj.image:
public_url = os.environ.get('PUBLIC_URL', 'http://127.0.0.1:8000').rstrip('/')
public_url = public_url.replace("'", "")
return mark_safe(f'<img src="{public_url}/media/{obj.image.name}" width="100px" height="100px"')
else:
return
class VisitAdmin(admin.ModelAdmin):
list_display = ('location', 'start_date', 'end_date', 'notes')
list_filter = ('start_date', 'end_date')
search_fields = ('notes',)
def image_display(self, obj):
if obj.image: # Ensure this field matches your model's image field
public_url = os.environ.get('PUBLIC_URL', 'http://127.0.0.1:8000').rstrip('/')
public_url = public_url.replace("'", "")
return mark_safe(f'<img src="{public_url}/media/{obj.image.name}" width="100px" height="100px"')
else:
return
image_display.short_description = 'Image Preview'
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'display_name', 'icon')
search_fields = ('name', 'display_name')
class CollectionAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'is_public')
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.register(Location, LocationAdmin)
admin.site.register(Collection, CollectionAdmin)
admin.site.register(Visit, VisitAdmin)
admin.site.register(Country, CountryAdmin)
admin.site.register(Region, RegionAdmin)
admin.site.register(VisitedRegion)
admin.site.register(Transportation)
admin.site.register(Note)
admin.site.register(Checklist)
admin.site.register(ChecklistItem)
admin.site.register(LocationImage, LocationImageAdmin)
admin.site.register(Category, CategoryAdmin)
admin.site.register(City, CityAdmin)
admin.site.register(VisitedCity)
admin.site.register(Attachment)
admin.site.register(Lodging)
admin.site.site_header = 'AdventureLog Admin'
admin.site.site_title = 'AdventureLog Admin Site'
admin.site.index_title = 'Welcome to AdventureLog Admin Page'