Using reverse to shortcut URLs, addressing compatibilities of sorts although am running the following;
dj-database-url==0.5.0
Django==2.1.4
django-crispy-forms==1.7.2
gunicorn==19.9.0
mysqlclient==1.3.14
Pillow==5.3.0
psycopg2==2.7.6.1
pytz==2018.7
My problem is that now my "detail" isn't working.
What do I have to do, please, to get the details working?
**********Link in template:
<ul>
{% for obj in object_list %}
<li><a href='{{ obj.get_absolute_url }}'> {{ obj }} </a><br/>
{{ obj.name }} {{ obj.location }} {{ obj.category }} {{ obj.timestamp }} {{ obj.updated }} </li>
{% endfor %}
</ul>
*********URL in App:
from django.conf.urls import url
from restaurants.views import (
# restaurant_createview,
# restaurant_listview,
RestaurantListView,
RestaurantDetailView,
RestaurantCreateView
)
app_name = 'restaurants'
urlpatterns = [
url(r'$', RestaurantListView.as_view(), name='list'),
url(r'^create/$', RestaurantCreateView.as_view(), name='create'), # RestaurantCreateView.as_view()),
url(r'^(?P<slug>[\w-]+)/$', RestaurantDetailView.as_view(), name='detail'),
]
*****************Main URLs
from django.conf.urls import url, include
from django.contrib import admin
from django.views.generic import TemplateView
from django.contrib.auth.views import LoginView
from restaurants.views import (
restaurant_createview,
restaurant_listview,
RestaurantListView,
RestaurantDetailView,
RestaurantCreateView
)
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^$', TemplateView.as_view(template_name = 'home.html'), name='home'),
url(r'^login/$', LoginView.as_view(), name='login'),
url('restaurants/', include('restaurants.urls', namespace='restaurants')),
url(r'^about/$', TemplateView.as_view(template_name = 'about.html'), name='about'),
url(r'^contact/$', TemplateView.as_view(template_name = 'contact.html'), name='contact'),
]
**********************Model
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.urls import reverse
from .utils import unique_slug_generator
from .validators import validate_category
User = settings.AUTH_USER_MODEL
class RestaurantLocation(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE) #
class_instance.model_set.all # check out - Django Models Unleashed
JOINCFE.com
name = models.CharField(max_length=120)
location = models.CharField(max_length=120, null=True, blank=True)
category = models.CharField(max_length=120, null=True, blank=True, validators=[validate_category])
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(null=True, blank=True)
def __str__(self):
return self.name
def get_absolute_url(self): #get_absolute_url
#return f"/restaurants/{self.slug}" Removed in order to use reverse - url resolvers
return reverse('restaurants:detail', kwargs={'slug': self.slug})
#changed from restaurants-detailto us the restaurants namespace
@property
def title(self):
return self.name #object.title
def rl_pre_save_receiver(sender, instance, *args, **kwargs):
instance.category = instance.category.capitalize()
if not instance.slug:
instance.slug = unique_slug_generator(instance)
#def rl_post_save_receiver(sender, instance, created, *args, **kwargs):
# print('saved')
# print(instance.timestamp)
# if not instance.slug:
# instance.slug = unique_slug_generator(instance)
# instance.save()
pre_save.connect(rl_pre_save_receiver, sender=RestaurantLocation)
#pre_save.connect(rl_post_save_receiver, sender=RestaurantLocation)
**************Views
from django.contrib.auth.decorators import login_required # login decorator, forces u to login before u see form!
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views import View
from django.views.generic import TemplateView, ListView, DetailView, CreateView
from .forms import RestaurantCreateForm, RestaurantLocationCreateForm
from .models import RestaurantLocation
# Create your views here.
# class based view
@login_required()
def restaurant_createview(request):
form = RestaurantLocationCreateForm(request.POST or None)
errors = None
if form.is_valid():
# form.save() --- This is done by default in this FBV
if request.user.is_authenticated:
instance = form.save(commit=False)
# customise
# like a pre_save
instance.owner = request.user # User is of AnonymousUser classif not logged in
instance.save()
# like a post_save
return HttpResponseRedirect("/restaurants/")
else:
return HttpResponseRedirect("/login/")
if form.errors:
errors = form.errors
template_name = 'restaurants/form.html'
context = {"form": form, "errors": errors}
return render(request, template_name, context)
def restaurant_listview(request):
template_name = 'restaurants/restaurants_list.html'
queryset = RestaurantLocation.objects.all()
context = {
"object_list": queryset
}
return render(request, template_name, context)
def restaurant_detailview(request, slug):
template_name = 'restaurants/restaurantslocation_detail.html'
obj = RestaurantLocation.objects.get(slug=slug)
context = {
"object": obj
}
return render(request, template_name, context)
class RestaurantListView(ListView):
def get_queryset(self):
slug = self.kwargs.get("slug")
if slug:
queryset = RestaurantLocation.objects.filter(
Q(category__iexact=slug) |
Q(category__icontains=slug)
)
else:
queryset = RestaurantLocation.objects.all()
return queryset
class RestaurantDetailView(DetailView):
queryset = RestaurantLocation.objects.all() #.filter(category__iexact='asian') # fitler by user
class RestaurantCreateView(LoginRequiredMixin, CreateView):
form_class = RestaurantLocationCreateForm
login_url = '/login/'
template_name = 'restaurants/form.html'
#success_url = '/restaurants/' Removed so we can do get_absolute_url
def form_valid(self, form):
instance = form.save(commit=False) # first avoid saving...
instance.owner = self.request.user # LoginRequiredMixin ensures request.user is authenticated
return super(RestaurantCreateView, self).form_valid(form) # similar to form.save() in the FBV --- Saving here
Please, help.
Cheers.