feat: Add SearchSubscriptions
This commit is contained in:
parent
be97ac32fb
commit
27b7e47f18
25
src/fellchensammlung/migrations/0028_searchsubscription.py
Normal file
25
src/fellchensammlung/migrations/0028_searchsubscription.py
Normal 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)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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'))
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user