diff --git a/fm_proj/settings.py b/fm_proj/settings.py index 4f80ada..c89ab12 100644 --- a/fm_proj/settings.py +++ b/fm_proj/settings.py @@ -9,156 +9,157 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.9/ref/settings/ """ - import os + import dj_database_url # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.environ.get('secret_key') +SECRET_KEY = os.environ.get("secret_key") # SECURITY WARNING: don't run with debug turned on in production! -if os.environ.get('debug') == 'True': +if os.environ.get("debug") == "True": DEBUG = True else: DEBUG = False ALLOWED_HOSTS = [ - 'fm-review-stage.herokuapp.com', - 'fathen.co', - 'www.fathen.co', - '127.0.0.1', - '127.0.0.1:8000', - 'fathen.dhcrain.com' + "fm-review-stage.herokuapp.com", + "fathen.co", + "www.fathen.co", + "127.0.0.1", + "127.0.0.1:8000", + "fathen.dhcrain.com", ] LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'verbose': { - 'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' + - 'pathname=%(pathname)s lineno=%(lineno)s ' + - 'funcname=%(funcName)s %(message)s'), - 'datefmt': '%Y-%m-%d %H:%M:%S' + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "verbose": { + "format": ("%(asctime)s [%(process)d] [%(levelname)s] " + + "pathname=%(pathname)s lineno=%(lineno)s " + + "funcname=%(funcName)s %(message)s"), + "datefmt": + "%Y-%m-%d %H:%M:%S", + }, + "simple": { + "format": "%(levelname)s %(message)s" }, - 'simple': { - 'format': '%(levelname)s %(message)s' - } }, - 'handlers': { - 'null': { - 'level': 'DEBUG', - 'class': 'logging.NullHandler', + "handlers": { + "null": { + "level": "DEBUG", + "class": "logging.NullHandler", + }, + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", }, - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'verbose' - } }, - 'loggers': { - 'testlogger': { - 'handlers': ['console'], - 'level': 'INFO', + "loggers": { + "testlogger": { + "handlers": ["console"], + "level": "INFO", } - } + }, } # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'review_app', - 'hvad', - 'review', - 'generic_positions', - 'storages', - 'rest_framework', - 'rest_framework_docs', - 'captcha', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "review_app", + "hvad", + "review", + "generic_positions", + "storages", + "rest_framework", + "rest_framework_docs", + "captcha", ] MIDDLEWARE_CLASSES = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'whitenoise.middleware.WhiteNoiseMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.auth.middleware.SessionAuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "whitenoise.middleware.WhiteNoiseMiddleware", ] -ROOT_URLCONF = 'fm_proj.urls' +ROOT_URLCONF = "fm_proj.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': ['templates'], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": ["templates"], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'fm_proj.wsgi.application' - +WSGI_APPLICATION = "fm_proj.wsgi.application" # Database # https://docs.djangoproject.com/en/1.9/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": os.path.join(BASE_DIR, "db.sqlite3"), } } - # Password validation # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": + "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": + "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": + "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": + "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] - # Internationalization # https://docs.djangoproject.com/en/1.9/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'America/New_York' +TIME_ZONE = "America/New_York" USE_I18N = True @@ -170,44 +171,40 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ -STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') -STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(PROJECT_ROOT, "staticfiles") +STATIC_URL = "/static/" # Extra places for collectstatic to find static files. -STATICFILES_DIRS = ( - os.path.join(PROJECT_ROOT, 'static'), -) +STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, "static"), ) # Simplified static file serving. # https://warehouse.python.org/project/whitenoise/ -STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage' +STATICFILES_STORAGE = "whitenoise.django.GzipManifestStaticFilesStorage" # STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage' # Error on user_media/css/img/progressbar.gif - db_from_env = dj_database_url.config() -DATABASES['default'].update(db_from_env) +DATABASES["default"].update(db_from_env) MEDIA_ROOT = BASE_DIR -MEDIA_URL = '/media/' - +MEDIA_URL = "/media/" # Django-starages / AWS S3 / https://www.caktusgroup.com/blog/2014/11/10/Using-Amazon-S3-to-store-your-Django-sites-static-and-media-files/ AWS_HEADERS = { # see http://developer.yahoo.com/performance/rules.html#expires - 'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT', - 'Cache-Control': 'max-age=94608000', - } + "Expires": "Thu, 31 Dec 2099 20:00:00 GMT", + "Cache-Control": "max-age=94608000", +} # AWS_STORAGE_BUCKET_NAME = os.environ.get('aws_bucket_name') -AWS_STORAGE_BUCKET_NAME = os.environ.get('NOTHING_HERE') -AWS_ACCESS_KEY_ID = os.environ['aws_access_key_id'] -AWS_SECRET_ACCESS_KEY = os.environ['aws_secret_access_key'] +AWS_STORAGE_BUCKET_NAME = os.environ.get("NOTHING_HERE") +AWS_ACCESS_KEY_ID = os.environ["aws_access_key_id"] +AWS_SECRET_ACCESS_KEY = os.environ["aws_secret_access_key"] # Tell django-storages that when coming up with the URL for an item in S3 storage, keep # it simple - just use this domain plus the path. (If this isn't set, things get complicated). # This controls how the `static` template tag from `staticfiles` gets expanded, if you're using it. # We also use it in the next setting. -AWS_S3_CUSTOM_DOMAIN = '{}.s3.amazonaws.com'.format(AWS_STORAGE_BUCKET_NAME) +AWS_S3_CUSTOM_DOMAIN = "{}.s3.amazonaws.com".format(AWS_STORAGE_BUCKET_NAME) if AWS_STORAGE_BUCKET_NAME: # This is used by the `static` template tag from `static`, if you're using that. Or if anything else @@ -217,58 +214,63 @@ AWS_S3_FILE_OVERWRITE = False # Tell the staticfiles app to use S3Boto storage when writing the collected static files (when # you run `collectstatic`). - STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage' + STATICFILES_STORAGE = "storages.backends.s3boto.S3BotoStorage" # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html # DEFAULT_FILE_STORAGE = 'libs.storages.S3Storage.S3Storage' - DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' - - STATICFILES_LOCATION = 'static' + DEFAULT_FILE_STORAGE = "storages.backends.s3boto.S3BotoStorage" + STATICFILES_LOCATION = "static" # For django-review # this would use a RadioSelect instead of the default Select -REVIEW_FORM_CHOICE_WIDGET = 'django.forms.widgets.RadioSelect' +REVIEW_FORM_CHOICE_WIDGET = "django.forms.widgets.RadioSelect" # Limit to 1 review per user per item REVIEW_FORM_CHOICE_WIDGET REVIEW_AVOID_MULTIPLE_REVIEWS = True # new redirect after review -REVIEW_UPDATE_SUCCESS_URL = lambda review: review.reviewed_item.get_absolute_url() + + +def REVIEW_UPDATE_SUCCESS_URL(review): + return review.reviewed_item.get_absolute_url() REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. - 'DEFAULT_PERMISSION_CLASSES': [ - 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' - ], - 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', - 'PAGE_SIZE': 25, - 'DEFAULT_THROTTLE_CLASSES': ( - 'rest_framework.throttling.AnonRateThrottle', - 'rest_framework.throttling.UserRateThrottle' + "DEFAULT_PERMISSION_CLASSES": + ["rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly"], + "DEFAULT_PAGINATION_CLASS": + "rest_framework.pagination.LimitOffsetPagination", + "PAGE_SIZE": + 25, + "DEFAULT_THROTTLE_CLASSES": ( + "rest_framework.throttling.AnonRateThrottle", + "rest_framework.throttling.UserRateThrottle", ), - 'DEFAULT_THROTTLE_RATES': { - 'anon': '100/day', - 'user': '1000/day' - } + "DEFAULT_THROTTLE_RATES": { + "anon": "100/day", + "user": "1000/day" + }, } -EMAIL_HOST_USER = 'fathen.co@gmail.com' -EMAIL_HOST_PASSWORD = os.environ['email_password'] -EMAIL_HOST = 'smtp.gmail.com' +EMAIL_HOST_USER = "fathen.co@gmail.com" +EMAIL_HOST_PASSWORD = os.environ["email_password"] +EMAIL_HOST = "smtp.gmail.com" EMAIL_USE_TLS = True EMAIL_PORT = 587 # Celery settings from https://www.cloudamqp.com/docs/celery.html -BROKER_URL = os.environ.get('CLOUDAMQP_URL') +BROKER_URL = os.environ.get("CLOUDAMQP_URL") BROKER_POOL_LIMIT = 1 # Will decrease connection usage BROKER_HEARTBEAT = None # We're using TCP keep-alive instead -BROKER_CONNECTION_TIMEOUT = 30 # May require a long timeout due to Linux DNS timeouts etc -CELERY_RESULT_BACKEND = None # AMQP is not recommended as result backend as it creates thousands of queues +# May require a long timeout due to Linux DNS timeouts etc +BROKER_CONNECTION_TIMEOUT = 30 +# AMQP is not recommended as result backend as it creates thousands of queues +CELERY_RESULT_BACKEND = None CELERY_SEND_EVENTS = False # Will not create celeryev.* queues -CELERY_EVENT_QUEUE_EXPIRES = 60 # Will delete all celeryev. queues without consumers after 1 minute. - +# Will delete all celeryev. queues without consumers after 1 minute. +CELERY_EVENT_QUEUE_EXPIRES = 60 -RECAPTCHA_PUBLIC_KEY = os.environ['RECAPTCHA_PUBLIC_KEY'] -RECAPTCHA_PRIVATE_KEY = os.environ['RECAPTCHA_PRIVATE_KEY'] +RECAPTCHA_PUBLIC_KEY = os.environ["RECAPTCHA_PUBLIC_KEY"] +RECAPTCHA_PRIVATE_KEY = os.environ["RECAPTCHA_PRIVATE_KEY"] NOCAPTCHA = True diff --git a/review_app/forms.py b/review_app/forms.py index 4482a5f..4ee959c 100644 --- a/review_app/forms.py +++ b/review_app/forms.py @@ -1,29 +1,30 @@ +from captcha.fields import ReCaptchaField +from django import forms from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.core.validators import validate_email -from django import forms -from review_app.models import Status from django.utils.translation import ugettext_lazy as _ -from captcha.fields import ReCaptchaField -class StatusCreateForm(forms.ModelForm): +from review_app.models import Status + +class StatusCreateForm(forms.ModelForm): class Meta: model = Status - fields = ['status_comment', 'status_present', 'status_picture'] + fields = ["status_comment", "status_present", "status_picture"] labels = { - 'status_comment': _('Status'), - 'status_present': _('Will you be there?'), - 'status_picture': _('Picture') + "status_comment": _("Status"), + "status_present": _("Will you be there?"), + "status_picture": _("Picture"), } help_texts = { - 'status_present': _('Tell your customers if you will be there.'), + "status_present": _("Tell your customers if you will be there."), } class ContactForm(forms.Form): - required_css_class = 'required' + required_css_class = "required" captcha = ReCaptchaField() name = forms.CharField(required=True) email = forms.EmailField(required=True) @@ -33,7 +34,7 @@ class ContactForm(forms.Form): # https://djangosnippets.org/snippets/3043/ class UserCreationEmailForm(UserCreationForm): - required_css_class = 'required' + required_css_class = "required" captcha = ReCaptchaField() # we are using email as username so override label and validators username = forms.CharField( @@ -41,7 +42,9 @@ class UserCreationEmailForm(UserCreationForm): max_length=30, required=True, validators=[validate_email], - help_text=_("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.") + help_text= + _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only." + ), ) class Meta: diff --git a/review_app/migrations/0012_auto_20170907_2154.py b/review_app/migrations/0012_auto_20170907_2154.py index 4ca3d7f..1ea653d 100644 --- a/review_app/migrations/0012_auto_20170907_2154.py +++ b/review_app/migrations/0012_auto_20170907_2154.py @@ -2,76 +2,93 @@ # Generated by Django 1.9.7 on 2017-09-07 21:54 from __future__ import unicode_literals -from django.db import migrations, models import django.db.models.deletion import localflavor.us.models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): dependencies = [ - ('review_app', '0011_auto_20160731_1737'), + ("review_app", "0011_auto_20160731_1737"), ] operations = [ migrations.AlterField( - model_name='profile', - name='profile_fm_like', - field=models.ManyToManyField(blank=True, related_name='fm_likes', to='review_app.FarmersMarket'), + model_name="profile", + name="profile_fm_like", + field=models.ManyToManyField(blank=True, + related_name="fm_likes", + to="review_app.FarmersMarket"), ), migrations.AlterField( - model_name='profile', - name='profile_vendor_like', - field=models.ManyToManyField(blank=True, related_name='vendor_likes', to='review_app.Vendor'), + model_name="profile", + name="profile_vendor_like", + field=models.ManyToManyField(blank=True, + related_name="vendor_likes", + to="review_app.Vendor"), ), migrations.AlterField( - model_name='vendor', - name='at_farmers_market', - field=models.ManyToManyField(to='review_app.FarmersMarket', verbose_name='Located here'), + model_name="vendor", + name="at_farmers_market", + field=models.ManyToManyField(to="review_app.FarmersMarket", + verbose_name="Located here"), ), migrations.AlterField( - model_name='vendor', - name='vendor_banner_picture', - field=models.ImageField(blank=True, upload_to='vendor_images', verbose_name='Banner Picture'), + model_name="vendor", + name="vendor_banner_picture", + field=models.ImageField(blank=True, + upload_to="vendor_images", + verbose_name="Banner Picture"), ), migrations.AlterField( - model_name='vendor', - name='vendor_contact_email', - field=models.EmailField(max_length=254, verbose_name='Email'), + model_name="vendor", + name="vendor_contact_email", + field=models.EmailField(max_length=254, verbose_name="Email"), ), migrations.AlterField( - model_name='vendor', - name='vendor_contact_name', - field=models.CharField(max_length=50, verbose_name='Contact Name'), + model_name="vendor", + name="vendor_contact_name", + field=models.CharField(max_length=50, verbose_name="Contact Name"), ), migrations.AlterField( - model_name='vendor', - name='vendor_description', - field=models.TextField(blank=True, verbose_name='Description'), + model_name="vendor", + name="vendor_description", + field=models.TextField(blank=True, verbose_name="Description"), ), migrations.AlterField( - model_name='vendor', - name='vendor_name', - field=models.CharField(max_length=100, verbose_name='Vendor Name'), + model_name="vendor", + name="vendor_name", + field=models.CharField(max_length=100, verbose_name="Vendor Name"), ), migrations.AlterField( - model_name='vendor', - name='vendor_phone', - field=localflavor.us.models.PhoneNumberField(blank=True, verbose_name='Phone'), + model_name="vendor", + name="vendor_phone", + field=localflavor.us.models.PhoneNumberField(blank=True, + verbose_name="Phone"), ), migrations.AlterField( - model_name='vendor', - name='vendor_picture', - field=models.ImageField(blank=True, upload_to='vendor_images', verbose_name='Profile Picture'), + model_name="vendor", + name="vendor_picture", + field=models.ImageField(blank=True, + upload_to="vendor_images", + verbose_name="Profile Picture"), ), migrations.AlterField( - model_name='vendor', - name='vendor_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='review_app.VendorType', verbose_name='Catergory'), + model_name="vendor", + name="vendor_type", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="review_app.VendorType", + verbose_name="Catergory", + ), ), migrations.AlterField( - model_name='vendor', - name='vendor_website', - field=models.URLField(blank=True, verbose_name='Website'), + model_name="vendor", + name="vendor_website", + field=models.URLField(blank=True, verbose_name="Website"), ), ] diff --git a/review_app/models.py b/review_app/models.py index 2ae1661..69ea899 100644 --- a/review_app/models.py +++ b/review_app/models.py @@ -1,12 +1,13 @@ -from django.db import models -# from django.template.defaultfilters import slugify +import datetime + from autoslug import AutoSlugField -from localflavor.us.models import PhoneNumberField +from django.core.urlresolvers import reverse +from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver -from django.core.urlresolvers import reverse -import datetime +from localflavor.us.models import PhoneNumberField from review.templatetags.review_tags import total_review_average +# from django.template.defaultfilters import slugify class VendorType(models.Model): @@ -17,20 +18,26 @@ def __str__(self): class FarmersMarket(models.Model): - fm_user = models.ForeignKey('auth.User') + fm_user = models.ForeignKey("auth.User") fm_name = models.CharField(max_length=100) # https://pypi.python.org/pypi/django-autoslug - fm_slug = AutoSlugField(populate_from='fm_name', unique=True, editable=True, blank=True) + fm_slug = AutoSlugField(populate_from="fm_name", + unique=True, + editable=True, + blank=True) fm_description = models.TextField(blank=True) fm_picture = models.ImageField(upload_to="fm_images", blank=True) fm_banner_picture = models.ImageField(upload_to="fm_images", blank=True) fm_contact_name = models.CharField(max_length=50) fm_contact_email = models.EmailField() fm_website = models.URLField(blank=True) - OPEN_AIR = 'Open-Air' - OA_COVERED = 'Open-Air/Covered' - facility_choices = ((OPEN_AIR, 'Open-Air'), (OA_COVERED, 'Open-Air/Covered')) - fm_facility_type = models.CharField(max_length=20, blank=True, choices=facility_choices) + OPEN_AIR = "Open-Air" + OA_COVERED = "Open-Air/Covered" + facility_choices = ((OPEN_AIR, "Open-Air"), (OA_COVERED, + "Open-Air/Covered")) + fm_facility_type = models.CharField(max_length=20, + blank=True, + choices=facility_choices) fm_county = models.CharField(max_length=20, blank=True) fm_address = models.CharField(max_length=75, blank=True) fm_lat = models.FloatField(blank=True, null=True) @@ -48,7 +55,7 @@ def __str__(self): return self.fm_name class Meta: - ordering = ['fm_name'] + ordering = ["fm_name"] @property def fm_picture_url(self): @@ -67,28 +74,41 @@ def fm_banner_picture_url(self): return "../../static/review_app/img/greens.jpg" def get_absolute_url(self): - return reverse('farmers_market_detail_view', kwargs={'fm_slug': self.fm_slug}) + return reverse("farmers_market_detail_view", + kwargs={"fm_slug": self.fm_slug}) @property def get_rating(self): - return (total_review_average(self) / 20) + return total_review_average(self) / 20 class Vendor(models.Model): - vendor_user = models.ForeignKey('auth.User') - at_farmers_market = models.ManyToManyField("FarmersMarket", verbose_name='Located here') - vendor_name = models.CharField(max_length=100, verbose_name='Vendor Name') + vendor_user = models.ForeignKey("auth.User") + at_farmers_market = models.ManyToManyField("FarmersMarket", + verbose_name="Located here") + vendor_name = models.CharField(max_length=100, verbose_name="Vendor Name") # https://pypi.python.org/pypi/django-autoslug - vendor_slug = AutoSlugField(populate_from='vendor_name', unique=True, editable=True) - vendor_description = models.TextField(blank=True, verbose_name='Description') - vendor_picture = models.ImageField(upload_to="vendor_images", blank=True, verbose_name='Profile Picture') - vendor_banner_picture = models.ImageField(upload_to="vendor_images", blank=True, verbose_name='Banner Picture') - vendor_contact_name = models.CharField(max_length=50, verbose_name='Contact Name') - vendor_contact_email = models.EmailField(verbose_name='Email') - vendor_website = models.URLField(blank=True, verbose_name='Website') + vendor_slug = AutoSlugField(populate_from="vendor_name", + unique=True, + editable=True) + vendor_description = models.TextField(blank=True, + verbose_name="Description") + vendor_picture = models.ImageField(upload_to="vendor_images", + blank=True, + verbose_name="Profile Picture") + vendor_banner_picture = models.ImageField(upload_to="vendor_images", + blank=True, + verbose_name="Banner Picture") + vendor_contact_name = models.CharField(max_length=50, + verbose_name="Contact Name") + vendor_contact_email = models.EmailField(verbose_name="Email") + vendor_website = models.URLField(blank=True, verbose_name="Website") # https://pypi.python.org/pypi/django-localflavor - vendor_phone = PhoneNumberField(blank=True, verbose_name='Phone') - vendor_type = models.ForeignKey(VendorType, blank=True, null=True, verbose_name='Catergory') + vendor_phone = PhoneNumberField(blank=True, verbose_name="Phone") + vendor_type = models.ForeignKey(VendorType, + blank=True, + null=True, + verbose_name="Catergory") vendor_updated = models.DateTimeField(auto_now=True) def __str__(self): @@ -97,7 +117,8 @@ def __str__(self): @property def get_vendor_order_by(self): one_week = datetime.datetime.now() + datetime.timedelta(days=-7) - return self.status_set.filter(status_created__gt=one_week).order_by("status_present") + return self.status_set.filter( + status_created__gt=one_week).order_by("status_present") @property def get_recent_status(self): @@ -121,23 +142,32 @@ def vendor_banner_picture_url(self): return "../../static/review_app/img/pea.jpg" def get_absolute_url(self): - return reverse('vendor_detail_view', kwargs={'vendor_slug': self.vendor_slug}) + return reverse("vendor_detail_view", + kwargs={"vendor_slug": self.vendor_slug}) @property def get_rating(self): - return (total_review_average(self) / 20) + return total_review_average(self) / 20 class Profile(models.Model): - FARMERS_MARKET = 'Farmers Market' - VENDOR = 'Vendor' - REVIEWER = 'Reviewer' - user_type_choices = ((FARMERS_MARKET, 'Farmers Market'), (VENDOR, 'Vendor'), (REVIEWER, 'Reviewer')) - profile_user = models.OneToOneField('auth.User') + FARMERS_MARKET = "Farmers Market" + VENDOR = "Vendor" + REVIEWER = "Reviewer" + user_type_choices = ( + (FARMERS_MARKET, "Farmers Market"), + (VENDOR, "Vendor"), + (REVIEWER, "Reviewer"), + ) + profile_user = models.OneToOneField("auth.User") user_type = models.CharField(max_length=15, choices=user_type_choices) profile_picture = models.ImageField(upload_to="profile_images", blank=True) - profile_fm_like = models.ManyToManyField(FarmersMarket, blank=True, related_name='fm_likes') - profile_vendor_like = models.ManyToManyField(Vendor, blank=True, related_name='vendor_likes') + profile_fm_like = models.ManyToManyField(FarmersMarket, + blank=True, + related_name="fm_likes") + profile_vendor_like = models.ManyToManyField(Vendor, + blank=True, + related_name="vendor_likes") def __str__(self): return str(self.profile_user) @@ -151,15 +181,19 @@ def profile_picture_url(self): class Status(models.Model): - status_user = models.ForeignKey('auth.User') + status_user = models.ForeignKey("auth.User") status_vendor = models.ForeignKey(Vendor, null=True, blank=True) status_fm = models.ForeignKey(FarmersMarket, null=True, blank=True) - YES = 'Yes' - NO = 'No' - NO_RESPONSE = 'No Response' - present_choices = ((YES, 'Yes'), (NO, 'No'), (NO_RESPONSE, "No Response")) - status_present = models.CharField(max_length=11, choices=present_choices, default=NO_RESPONSE) - status_picture = models.ImageField(upload_to="status_images", blank=True, null=True) + YES = "Yes" + NO = "No" + NO_RESPONSE = "No Response" + present_choices = ((YES, "Yes"), (NO, "No"), (NO_RESPONSE, "No Response")) + status_present = models.CharField(max_length=11, + choices=present_choices, + default=NO_RESPONSE) + status_picture = models.ImageField(upload_to="status_images", + blank=True, + null=True) status_comment = models.TextField(blank=True) status_created = models.DateTimeField(auto_now_add=True) @@ -167,7 +201,7 @@ def __str__(self): return str(self.status_comment) class Meta: - ordering = ['-status_created'] + ordering = ["-status_created"] @property def get_status_object(self): @@ -177,7 +211,7 @@ def get_status_object(self): return self.status_fm -@receiver(post_save, sender='auth.User') +@receiver(post_save, sender="auth.User") def create_user_profile(**kwargs): created = kwargs.get("created") instance = kwargs.get("instance") diff --git a/review_app/views.py b/review_app/views.py index 7ddea62..37adad3 100644 --- a/review_app/views.py +++ b/review_app/views.py @@ -1,40 +1,62 @@ import datetime import operator -import requests -import geocoder import os from functools import reduce -from django.http import HttpResponseRedirect -from django.db.models import Case, When, Q -from django.core.urlresolvers import reverse_lazy, reverse + +import geocoder +import requests +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.models import User +from django.contrib.messages.views import SuccessMessageMixin +from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse_lazy +from django.db.models import Case +from django.db.models import Q +from django.db.models import When from django.http import Http404 +from django.http import HttpResponseRedirect +from django.views.generic import CreateView +from django.views.generic import DetailView +from django.views.generic import FormView +from django.views.generic import ListView +from django.views.generic import TemplateView +from django.views.generic import View +from django.views.generic.edit import DeleteView +from django.views.generic.edit import UpdateView +from review.forms import ReviewForm +from review.templatetags.review_tags import total_review_average + +from review_app.forms import ContactForm +from review_app.forms import StatusCreateForm +from review_app.forms import UserCreationEmailForm +from review_app.models import FarmersMarket +from review_app.models import Profile +from review_app.models import Status +from review_app.models import Vendor +from review_app.tasks import contact_email # from django.core.paginator import Paginator # from django.core.mail import send_mail # from fm_proj.settings import EMAIL_HOST_USER -from django.contrib.messages.views import SuccessMessageMixin -from review_app.tasks import contact_email # from django.shortcuts import render -from django.views.generic.edit import UpdateView, DeleteView -from django.views.generic import View, TemplateView, CreateView, DetailView, ListView, FormView -from django.contrib.auth.mixins import LoginRequiredMixin -from django.contrib.auth.models import User -from django.contrib.auth.forms import AuthenticationForm, UserCreationForm -from review_app.models import Profile, FarmersMarket, Vendor, Status -from review_app.forms import StatusCreateForm, ContactForm, UserCreationEmailForm -from review.templatetags.review_tags import total_review_average -from review.forms import ReviewForm class IndexView(ListView): - template_name = 'index.html' + template_name = "index.html" paginate_by = 10 def get_queryset(self): # http://stackoverflow.com/a/38390480/5119789 - reviews = [(total_review_average(market), market.pk) for market in FarmersMarket.objects.all()] - pk_list = [mkt[1] for mkt in sorted(reviews, key=lambda x: x[0], reverse=True)] - preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) - return FarmersMarket.objects.filter(pk__in=pk_list).order_by(preserved) # [:10] + reviews = [(total_review_average(market), market.pk) + for market in FarmersMarket.objects.all()] + pk_list = [ + mkt[1] for mkt in sorted(reviews, key=lambda x: x[0], reverse=True) + ] + preserved = Case( + *[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) + # [:10] + return FarmersMarket.objects.filter(pk__in=pk_list).order_by(preserved) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -43,70 +65,106 @@ def get_context_data(self, **kwargs): class FarmersMarketListView(ListView): - template_name = 'review_app/farmersmarkets_list.html' + template_name = "review_app/farmersmarkets_list.html" model = FarmersMarket paginate_by = 25 def get_queryset(self, **kwargs): - rated = self.request.GET.get('rated') - sort = self.request.GET.get('sort') + rated = self.request.GET.get("rated") + sort = self.request.GET.get("sort") if sort: return FarmersMarket.objects.all().order_by(sort) elif rated: # http://stackoverflow.com/a/38390480/5119789 - reviews = [(total_review_average(market), market.pk) for market in FarmersMarket.objects.all()] - pk_list = [mkt[1] for mkt in sorted(reviews, key=lambda x: x[0], reverse=True)] - preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) - return FarmersMarket.objects.filter(pk__in=pk_list).order_by(preserved) + reviews = [(total_review_average(market), market.pk) + for market in FarmersMarket.objects.all()] + pk_list = [ + mkt[1] + for mkt in sorted(reviews, key=lambda x: x[0], reverse=True) + ] + preserved = Case( + *[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) + return FarmersMarket.objects.filter( + pk__in=pk_list).order_by(preserved) else: return FarmersMarket.objects.all() class FarmersMarketDetailView(DetailView): model = FarmersMarket - slug_field = 'fm_slug' - slug_url_kwarg = 'fm_slug' + slug_field = "fm_slug" + slug_url_kwarg = "fm_slug" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - fm_slug = self.kwargs.get('fm_slug') - sort = self.request.GET.get('sort') - rated = self.request.GET.get('rated') + fm_slug = self.kwargs.get("fm_slug") + sort = self.request.GET.get("sort") + rated = self.request.GET.get("rated") # forecast = self.request.GET.get('forecast') location = FarmersMarket.objects.get(fm_slug=fm_slug) - api_key = os.environ['forecast_api'] - url = "https://api.forecast.io/forecast/{}/{},{}".format(api_key, location.fm_lat, location.fm_long) + api_key = os.environ["forecast_api"] + url = "https://api.forecast.io/forecast/{}/{},{}".format( + api_key, location.fm_lat, location.fm_long) response = requests.get(url).json() - if (location.fm_lat is not None or location.fm_long is not None): - context['forecast_summary'] = response['daily']['summary'] # weekly summary - context['forecast_iframe_url'] = "https://forecast.io/embed/#lat={}&lon={}&name={}".format(location.fm_lat, location.fm_long, location.fm_name) + if location.fm_lat is not None or location.fm_long is not None: + # weekly summary + context["forecast_summary"] = response["daily"]["summary"] + context[ + "forecast_iframe_url"] = "https://forecast.io/embed/#lat={}&lon={}&name={}".format( + location.fm_lat, location.fm_long, location.fm_name) if sort: - context['vendor_list'] = Vendor.objects.filter(at_farmers_market__fm_slug=fm_slug).order_by(sort) + context["vendor_list"] = Vendor.objects.filter( + at_farmers_market__fm_slug=fm_slug).order_by(sort) elif rated: # http://stackoverflow.com/a/38390480/5119789 - reviews = [(total_review_average(vendor), vendor.pk) for vendor in Vendor.objects.all()] - pk_list = [vendor[1] for vendor in sorted(reviews, key=lambda x: x[0], reverse=True)] - preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) - context['vendor_list'] = Vendor.objects.filter(at_farmers_market__fm_slug=fm_slug).filter(pk__in=pk_list).order_by(preserved) + reviews = [(total_review_average(vendor), vendor.pk) + for vendor in Vendor.objects.all()] + pk_list = [ + vendor[1] + for vendor in sorted(reviews, key=lambda x: x[0], reverse=True) + ] + preserved = Case( + *[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) + context["vendor_list"] = (Vendor.objects.filter( + at_farmers_market__fm_slug=fm_slug).filter( + pk__in=pk_list).order_by(preserved)) else: - context['vendor_list_present'] = Vendor.objects.prefetch_related('status_set').filter(at_farmers_market__fm_slug=fm_slug, status__status_present="Yes").distinct() - context['vendor_list_no'] = Vendor.objects.prefetch_related('status_set').filter(at_farmers_market__fm_slug=fm_slug, status__status_present="No").distinct() - context['vendor_list_nr_status'] = Vendor.objects.prefetch_related('status_set').filter(at_farmers_market__fm_slug=fm_slug, status__status_present="No Response").distinct() - context['vendor_list_nr'] = Vendor.objects.prefetch_related('status_set').filter(at_farmers_market__fm_slug=fm_slug, status__status_present=None).distinct() - context['vendor_list'] = Vendor.objects.prefetch_related('status_set').filter(at_farmers_market__fm_slug=fm_slug) # .order_by('status') + context["vendor_list_present"] = ( + Vendor.objects.prefetch_related("status_set").filter( + at_farmers_market__fm_slug=fm_slug, + status__status_present="Yes").distinct()) + context["vendor_list_no"] = ( + Vendor.objects.prefetch_related("status_set").filter( + at_farmers_market__fm_slug=fm_slug, + status__status_present="No").distinct()) + context["vendor_list_nr_status"] = ( + Vendor.objects.prefetch_related("status_set").filter( + at_farmers_market__fm_slug=fm_slug, + status__status_present="No Response", + ).distinct()) + context["vendor_list_nr"] = ( + Vendor.objects.prefetch_related("status_set").filter( + at_farmers_market__fm_slug=fm_slug, + status__status_present=None).distinct()) + context["vendor_list"] = Vendor.objects.prefetch_related( + "status_set").filter( + at_farmers_market__fm_slug=fm_slug) # .order_by('status') mrkt = FarmersMarket.objects.get(fm_slug=fm_slug) - google_api = os.environ['google_maps_api'] - map_url = "https://www.google.com/maps/embed/v1/place?key={}&q={}".format(google_api, mrkt.fm_address) - context['google_map'] = map_url - context['fm_status_form'] = StatusCreateForm() - context['review_form'] = ReviewForm(mrkt) + google_api = os.environ["google_maps_api"] + map_url = "https://www.google.com/maps/embed/v1/place?key={}&q={}".format( + google_api, mrkt.fm_address) + context["google_map"] = map_url + context["fm_status_form"] = StatusCreateForm() + context["review_form"] = ReviewForm(mrkt) """ removed one_week filter for demo purposes one_week = datetime.datetime.now() + datetime.timedelta(days=-7) """ - context['status_list'] = Status.objects.filter(status_fm=mrkt) # .filter(status_created__gt=one_week) - context['num_likes'] = location.fm_likes.count() - context['asdf'] = User.objects.get(username='asdf') # default 'owner' of all fm/v + context["status_list"] = Status.objects.filter( + status_fm=mrkt) # .filter(status_created__gt=one_week) + context["num_likes"] = location.fm_likes.count() + context["asdf"] = User.objects.get( + username="asdf") # default 'owner' of all fm/v return context @@ -116,96 +174,129 @@ class FarmersMarketStatusCreateView(LoginRequiredMixin, CreateView): def form_valid(self, form, **kwargs): status_form = form.save(commit=False) - fm_slug = self.kwargs.get('fm_slug') + fm_slug = self.kwargs.get("fm_slug") status_form.status_user = self.request.user status_form.status_fm = FarmersMarket.objects.get(fm_slug=fm_slug) return super().form_valid(form) def get_success_url(self): - fm_slug = self.kwargs.get('fm_slug') - return reverse('farmers_market_detail_view', args=(fm_slug,)) + fm_slug = self.kwargs.get("fm_slug") + return reverse("farmers_market_detail_view", args=(fm_slug, )) class FarmersMarketCreateView(LoginRequiredMixin, CreateView): model = FarmersMarket - fields = ['fm_name', 'fm_description', 'fm_contact_name', 'fm_contact_email', - 'fm_website', 'fm_facility_type', 'fm_county', 'fm_address', - 'fm_programs_accepted', 'fm_phone', 'fm_hrs_of_operation', - 'fm_seasons_of_operation', 'fm_handicap_accessible', 'fm_picture', 'fm_banner_picture'] + fields = [ + "fm_name", + "fm_description", + "fm_contact_name", + "fm_contact_email", + "fm_website", + "fm_facility_type", + "fm_county", + "fm_address", + "fm_programs_accepted", + "fm_phone", + "fm_hrs_of_operation", + "fm_seasons_of_operation", + "fm_handicap_accessible", + "fm_picture", + "fm_banner_picture", + ] def form_valid(self, form): fm_form = form.save(commit=False) fm_form.fm_user = self.request.user - fm_address = form.cleaned_data['fm_address'] + fm_address = form.cleaned_data["fm_address"] g = geocoder.google(fm_address) fm_form.fm_lat = g.latlng[0] fm_form.fm_long = g.latlng[1] return super().form_valid(form) def get_success_url(self): - return reverse('farmers_market_detail_view', args=(self.object.fm_slug,)) + return reverse("farmers_market_detail_view", + args=(self.object.fm_slug, )) class FarmersMarketUpdateView(LoginRequiredMixin, UpdateView): model = FarmersMarket - slug_field = 'fm_slug' - slug_url_kwarg = 'fm_slug' - fields = ['fm_name', 'fm_description', 'fm_contact_name', 'fm_contact_email', - 'fm_website', 'fm_facility_type', 'fm_county', 'fm_address', - 'fm_programs_accepted', 'fm_phone', 'fm_hrs_of_operation', - 'fm_seasons_of_operation', 'fm_handicap_accessible', 'fm_picture', 'fm_banner_picture'] + slug_field = "fm_slug" + slug_url_kwarg = "fm_slug" + fields = [ + "fm_name", + "fm_description", + "fm_contact_name", + "fm_contact_email", + "fm_website", + "fm_facility_type", + "fm_county", + "fm_address", + "fm_programs_accepted", + "fm_phone", + "fm_hrs_of_operation", + "fm_seasons_of_operation", + "fm_handicap_accessible", + "fm_picture", + "fm_banner_picture", + ] def form_valid(self, form): fm_form = form.save(commit=False) fm_form.fm_user = self.request.user - fm_address = form.cleaned_data['fm_address'] + fm_address = form.cleaned_data["fm_address"] g = geocoder.google(fm_address) fm_form.fm_lat = g.latlng[0] fm_form.fm_long = g.latlng[1] return super().form_valid(form) def get_success_url(self): - return reverse('farmers_market_detail_view', args=(self.object.fm_slug,)) + return reverse("farmers_market_detail_view", + args=(self.object.fm_slug, )) class ProfileFMLikeUpdateView(LoginRequiredMixin, View): - def post(self, request, fm_slug, pk): - fm_like = self.request.POST.get('fm_like') + fm_like = self.request.POST.get("fm_like") profile = Profile.objects.get(id=pk) - if fm_like == 'Favorite': - profile.profile_fm_like.add(FarmersMarket.objects.get(fm_slug=fm_slug)) + if fm_like == "Favorite": + profile.profile_fm_like.add( + FarmersMarket.objects.get(fm_slug=fm_slug)) else: - profile.profile_fm_like.remove(FarmersMarket.objects.get(fm_slug=fm_slug)) - return HttpResponseRedirect(reverse('farmers_market_detail_view', args=(fm_slug,))) + profile.profile_fm_like.remove( + FarmersMarket.objects.get(fm_slug=fm_slug)) + return HttpResponseRedirect( + reverse("farmers_market_detail_view", args=(fm_slug, ))) class ProfileVendorLikeView(LoginRequiredMixin, View): - def post(self, request, vendor_slug, pk): - vendor_like = self.request.POST.get('vendor_like') + vendor_like = self.request.POST.get("vendor_like") profile = Profile.objects.get(id=pk) - if vendor_like == 'Favorite': - profile.profile_vendor_like.add(Vendor.objects.get(vendor_slug=vendor_slug)) + if vendor_like == "Favorite": + profile.profile_vendor_like.add( + Vendor.objects.get(vendor_slug=vendor_slug)) else: - profile.profile_vendor_like.remove(Vendor.objects.get(vendor_slug=vendor_slug)) - return HttpResponseRedirect(reverse('vendor_detail_view', args=(vendor_slug,))) + profile.profile_vendor_like.remove( + Vendor.objects.get(vendor_slug=vendor_slug)) + return HttpResponseRedirect( + reverse("vendor_detail_view", args=(vendor_slug, ))) class VendorDetailView(DetailView): model = Vendor - slug_field = 'vendor_slug' - slug_url_kwarg = 'vendor_slug' + slug_field = "vendor_slug" + slug_url_kwarg = "vendor_slug" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - vendor_slug = self.kwargs.get('vendor_slug') + vendor_slug = self.kwargs.get("vendor_slug") vendor = Vendor.objects.get(vendor_slug=vendor_slug) - context['vendor_status_form'] = StatusCreateForm() - context['status_list'] = Status.objects.filter(status_vendor=vendor) - context['review_form'] = ReviewForm(vendor) - context['num_likes'] = vendor.vendor_likes.count() - context['asdf'] = User.objects.get(username='asdf') # default 'owner' of all fm/v + context["vendor_status_form"] = StatusCreateForm() + context["status_list"] = Status.objects.filter(status_vendor=vendor) + context["review_form"] = ReviewForm(vendor) + context["num_likes"] = vendor.vendor_likes.count() + context["asdf"] = User.objects.get( + username="asdf") # default 'owner' of all fm/v return context @@ -215,23 +306,32 @@ class VendorStatusCreateView(LoginRequiredMixin, CreateView): def form_valid(self, form, **kwargs): status_form = form.save(commit=False) - vendor_slug = self.kwargs.get('vendor_slug') + vendor_slug = self.kwargs.get("vendor_slug") status_form.status_user = self.request.user status_form.status_vendor = Vendor.objects.get(vendor_slug=vendor_slug) return super().form_valid(form) def get_success_url(self): - vendor_slug = self.kwargs.get('vendor_slug') - return reverse('vendor_detail_view', args=(vendor_slug,)) + vendor_slug = self.kwargs.get("vendor_slug") + return reverse("vendor_detail_view", args=(vendor_slug, )) class VendorCreateView(LoginRequiredMixin, CreateView): model = Vendor - slug_field = 'vendor_slug' - slug_url_kwarg = 'vendor_slug' - fields = ['at_farmers_market', 'vendor_name', 'vendor_description', 'vendor_contact_name', - 'vendor_contact_email', 'vendor_website', 'vendor_phone', 'vendor_type', - 'vendor_picture', 'vendor_banner_picture'] + slug_field = "vendor_slug" + slug_url_kwarg = "vendor_slug" + fields = [ + "at_farmers_market", + "vendor_name", + "vendor_description", + "vendor_contact_name", + "vendor_contact_email", + "vendor_website", + "vendor_phone", + "vendor_type", + "vendor_picture", + "vendor_banner_picture", + ] def form_valid(self, form): vendor_form = form.save(commit=False) @@ -239,16 +339,25 @@ def form_valid(self, form): return super().form_valid(form) def get_success_url(self): - return reverse('vendor_detail_view', args=(self.object.vendor_slug,)) + return reverse("vendor_detail_view", args=(self.object.vendor_slug, )) class VendorUpdateView(LoginRequiredMixin, UpdateView): model = Vendor - slug_field = 'vendor_slug' - slug_url_kwarg = 'vendor_slug' - fields = ['at_farmers_market', 'vendor_name', 'vendor_description', 'vendor_contact_name', - 'vendor_contact_email', 'vendor_website', 'vendor_phone', 'vendor_type', - 'vendor_picture', 'vendor_banner_picture'] + slug_field = "vendor_slug" + slug_url_kwarg = "vendor_slug" + fields = [ + "at_farmers_market", + "vendor_name", + "vendor_description", + "vendor_contact_name", + "vendor_contact_email", + "vendor_website", + "vendor_phone", + "vendor_type", + "vendor_picture", + "vendor_banner_picture", + ] def form_valid(self, form): vendor_form = form.save(commit=False) @@ -256,14 +365,14 @@ def form_valid(self, form): return super().form_valid(form) def get_success_url(self): - return reverse('vendor_detail_view', args=(self.object.vendor_slug,)) + return reverse("vendor_detail_view", args=(self.object.vendor_slug, )) class VendorDeleteView(LoginRequiredMixin, DeleteView): model = Vendor - slug_field = 'vendor_slug' - slug_url_kwarg = 'vendor_slug' - success_url = reverse_lazy('index_view') + slug_field = "vendor_slug" + slug_url_kwarg = "vendor_slug" + success_url = reverse_lazy("index_view") def get_object(self, queryset=None): vendor = super().get_object() @@ -274,9 +383,15 @@ def get_object(self, queryset=None): class StatusCreateView(LoginRequiredMixin, CreateView): model = Status - fields = ['status_vendor', 'status_fm', 'status_present', 'status_picture', 'status_comment'] - slug_field = 'slug' - slug_url_kwarg = 'slug' + fields = [ + "status_vendor", + "status_fm", + "status_present", + "status_picture", + "status_comment", + ] + slug_field = "slug" + slug_url_kwarg = "slug" def form_valid(self, form): status_form = form.save(commit=False) @@ -295,9 +410,9 @@ def get_success_url(self): class ProfileView(LoginRequiredMixin, UpdateView): - template_name = 'profile.html' - fields = ['user_type', 'profile_picture'] - success_url = reverse_lazy('profile_view') + template_name = "profile.html" + fields = ["user_type", "profile_picture"] + success_url = reverse_lazy("profile_view") def get_object(self, queryset=None): return self.request.user.profile @@ -311,7 +426,9 @@ def get_context_data(self, **kwargs): removed one_week filter for demo purposes one_week = datetime.datetime.now() + datetime.timedelta(days=-7) """ - context['status_list'] = Status.objects.filter(Q(status_vendor__in=vendor_favs) | Q(status_fm__in=fm_favs)) # .filter(status_created__gt=one_week) + context["status_list"] = Status.objects.filter( + Q(status_vendor__in=vendor_favs) + | Q(status_fm__in=fm_favs)) # .filter(status_created__gt=one_week) return context @@ -322,33 +439,42 @@ class SearchListView(ListView): def get_queryset(self): result = super().get_queryset() - query = self.request.GET.get('q') - search_type = self.request.GET.get('search_type') + query = self.request.GET.get("q") + search_type = self.request.GET.get("search_type") print(search_type) if query: query_list = query.split() - if search_type == 'fm_name': - result = result.filter(reduce(operator.and_, (Q(fm_name__icontains=q) for q in query_list))) - if search_type == 'fm_address': - result = result.filter(reduce(operator.and_, (Q(fm_address__icontains=q) for q in query_list))) - if search_type == 'fm_programs_accepted': - result = result.filter(reduce(operator.and_, (Q(fm_programs_accepted__icontains=q) for q in query_list))) + if search_type == "fm_name": + result = result.filter( + reduce(operator.and_, + (Q(fm_name__icontains=q) for q in query_list))) + if search_type == "fm_address": + result = result.filter( + reduce(operator.and_, + (Q(fm_address__icontains=q) for q in query_list))) + if search_type == "fm_programs_accepted": + result = result.filter( + reduce( + operator.and_, + (Q(fm_programs_accepted__icontains=q) + for q in query_list), + )) return result class ContactView(SuccessMessageMixin, FormView): form_class = ContactForm - template_name = 'review_app/contact.html' - success_url = reverse_lazy('contact_view') + template_name = "review_app/contact.html" + success_url = reverse_lazy("contact_view") success_message = "Thank you %(name)s, we will be in touch shortly" def form_valid(self, form): - name = form.cleaned_data.get('name') - from_email = form.cleaned_data.get('email') + name = form.cleaned_data.get("name") + from_email = form.cleaned_data.get("email") user = self.request.user - form_message = form.cleaned_data.get('message') - subject = form.cleaned_data.get('subject').strip() - from_email = form.cleaned_data.get('email') + form_message = form.cleaned_data.get("message") + subject = form.cleaned_data.get("subject").strip() + from_email = form.cleaned_data.get("email") # This is used to send the email with Celery delay contact_email(name, from_email, user, form_message, subject) return super().form_valid(form) @@ -364,8 +490,8 @@ class RegisterView(CreateView): success_url = reverse_lazy("login") def form_valid(self, form): - # we are using email as username so let's copy it also to email field - user = form.save(commit=False) - user.email = user.username - user.save() - return super().form_valid(form) + # we are using email as username so let's copy it also to email field + user = form.save(commit=False) + user.email = user.username + user.save() + return super().form_valid(form)