feat: Add SearchSubscriptions

This commit is contained in:
moanos [he/him] 2024-12-26 20:24:10 +01:00
parent be97ac32fb
commit 27b7e47f18
4 changed files with 52 additions and 3 deletions

View File

@ -0,0 +1,25 @@
# Generated by Django 5.1.1 on 2024-12-26 15:56
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('fellchensammlung', '0027_alter_animal_species_andoptionnoticenotification'),
]
operations = [
migrations.CreateModel(
name='SearchSubscription',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sex', models.CharField(choices=[('F', 'Weiblich'), ('M', 'Männlich'), ('M_N', 'Männlich, kastriert'), ('F_N', 'Weiblich, kastriert'), ('I', 'Intergeschlechtlich')], max_length=20)),
('radius', models.IntegerField(choices=[(20, '20 km'), (50, '50 km'), (100, '100 km'), (200, '200 km'), (500, '500 km')])),
('location', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fellchensammlung.location')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -546,6 +546,23 @@ class DistanceChoices(models.IntegerChoices):
TWO_HUNDRED = 200, '200 km' TWO_HUNDRED = 200, '200 km'
FIVE_HUNDRED = 500, '500 km' FIVE_HUNDRED = 500, '500 km'
class SearchSubscription(models.Model):
"""
SearchSubscriptions allow a user to get a notification when a new AdoptionNotice is added that matches their Search
criteria. Search criteria are location, SexChoicesWithAll and distance
Process:
- User performs a normal search
- User clicks Button "Subscribe to this Search"
- SearchSubscription is added to database
- On new AdoptionNotice: Check all existing SearchSubscriptions for matches
- For matches: Send notification to user of the SearchSubscription
"""
owner = models.ForeignKey(User, on_delete=models.CASCADE)
location = models.ForeignKey(Location, on_delete=models.PROTECT)
sex = models.CharField(max_length=20, choices=SexChoices.choices)
radius = models.IntegerField(choices=DistanceChoices.choices)
class Rule(models.Model): class Rule(models.Model):
""" """
@ -640,7 +657,6 @@ class ModerationAction(models.Model):
return f"[{self.action}]: {self.public_comment}" return f"[{self.action}]: {self.public_comment}"
class TextTypeChoices(models.TextChoices): class TextTypeChoices(models.TextChoices):
DEDICATED = "dedicated", _("Fest zugeordnet") DEDICATED = "dedicated", _("Fest zugeordnet")
MALE = "M", _("Männlich") MALE = "M", _("Männlich")
@ -648,6 +664,7 @@ class TextTypeChoices(models.TextChoices):
FEMALE_NEUTERED = "F_N", _("Weiblich, kastriert") FEMALE_NEUTERED = "F_N", _("Weiblich, kastriert")
INTER = "I", _("Intergeschlechtlich") INTER = "I", _("Intergeschlechtlich")
class Text(models.Model): class Text(models.Model):
""" """
Base class to store markdown content Base class to store markdown content
@ -769,6 +786,7 @@ class CommentNotification(BaseNotification):
def url(self): def url(self):
return self.comment.get_absolute_url return self.comment.get_absolute_url
class AndoptionNoticeNotification(BaseNotification): class AndoptionNoticeNotification(BaseNotification):
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('Vermittlung')) adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('Vermittlung'))
@ -776,6 +794,7 @@ class AndoptionNoticeNotification(BaseNotification):
def url(self): def url(self):
return self.adoption_notice.get_absolute_url return self.adoption_notice.get_absolute_url
class Subscriptions(models.Model): class Subscriptions(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('Nutzer*in')) owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('Nutzer*in'))
adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('AdoptionNotice')) adoption_notice = models.ForeignKey(AdoptionNotice, on_delete=models.CASCADE, verbose_name=_('AdoptionNotice'))

View File

@ -9,7 +9,12 @@
<input type="hidden" name="longitude" maxlength="200" id="longitude"> <input type="hidden" name="longitude" maxlength="200" id="longitude">
<input type="hidden" name="latitude" maxlength="200" id="latitude"> <input type="hidden" name="latitude" maxlength="200" id="latitude">
{{ search_form.as_p }} {{ search_form.as_p }}
<input class="btn" type="submit" value="Search" name="search"> <button class="btn" type="submit" value="search" name="search">
<i class="fas fa-search"></i> {% trans 'Suchen' %}
</button>
<button class="btn" type="submit" value="search" name="search">
<i class="fas fa-bell"></i> {% trans 'Suche abonnieren' %}
</button>
</form> </form>
{% if place_not_found %} {% if place_not_found %}
<p class="error">{% translate "Ort nicht gefunden" %}</p> <p class="error">{% translate "Ort nicht gefunden" %}</p>

View File

@ -16,7 +16,7 @@ from notfellchen import settings
from fellchensammlung import logger from fellchensammlung import logger
from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, ModerationAction, \ from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, ModerationAction, \
User, Location, AdoptionNoticeStatus, Subscriptions, CommentNotification, BaseNotification, RescueOrganization, \ User, Location, AdoptionNoticeStatus, Subscriptions, CommentNotification, BaseNotification, RescueOrganization, \
Species, Log, Timestamp, TrustLevel, SexChoicesWithAll Species, Log, Timestamp, TrustLevel, SexChoicesWithAll, SearchSubscription
from .forms import AdoptionNoticeForm, AdoptionNoticeFormWithDateWidget, ImageForm, ReportAdoptionNoticeForm, \ from .forms import AdoptionNoticeForm, AdoptionNoticeFormWithDateWidget, ImageForm, ReportAdoptionNoticeForm, \
CommentForm, ReportCommentForm, AnimalForm, \ CommentForm, ReportCommentForm, AnimalForm, \
AdoptionNoticeSearchForm, AnimalFormWithDateWidget, AdoptionNoticeFormWithDateWidgetAutoAnimal AdoptionNoticeSearchForm, AnimalFormWithDateWidget, AdoptionNoticeFormWithDateWidgetAutoAnimal