Я создаю простое приложение Django для обзоров различных объектов (ресторанов, автосервисов, автомоек и т. Д.).
Я начал с приложения, но вскоре столкнулся с первой проблемой. Каждый объект имеет особенности (но каждый тип объекта имеет различные особенности).
Например:
- В ресторанах есть сад, детская площадка, места, тип кухни и т. Д.
- автомойки имеют внешнюю очистку, внутреннюю очистку и т. Д.
Итак, я начал строить типичную реализацию БД с таблицами ManyToMany
, но затем нашел Django Model Inheritance, поэтому я реализовал его вмое приложение, как вы можете видеть:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('user/<int:pk>/', views.UserObjectsView.as_view(), name='user-objects'),
path('add/', views.add_object, name='add-object'),
path('<str:category>/<int:pk>/', views.show_object, name='show-object'),
path('all/<str:category>/', views.show_all_objects, name="show-all-objects"),
]
models.py:
from django.db import models
from users.models import ProfileUser
from django.utils import timezone
# Create your models here.
class Object(models.Model):
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
address = models.CharField(max_length=300)
content = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
approved_object = models.BooleanField(default=False)
admin_seen = models.BooleanField(default=False)
def __str__(self):
return f"{self.title}"
class Restaurant(Object):
seats = models.IntegerField()
bulgarian_kitchen = models.BooleanField(default=False)
italian_kitchen = models.BooleanField(default=False)
french_kitchen = models.BooleanField(default=False)
is_garden = models.BooleanField(default=False)
is_playground = models.BooleanField(default=False)
class SportFitness(Object):
is_fitness_trainer = models.BooleanField(default=False)
class CarService(Object):
is_parts_clients = models.BooleanField(default=False)
class BeautySalon(Object):
is_hair_salon = models.BooleanField(default=False)
is_laser_epilation = models.BooleanField(default=False)
class FastFood(Object):
is_pizza = models.BooleanField(default=False)
is_duner = models.BooleanField(default=False)
is_seats = models.BooleanField(default=False)
class CarWash(Object):
is_external_cleaning = models.BooleanField(default=False)
is_internal_cleaning = models.BooleanField(default=False)
is_engine_cleaning = models.BooleanField(default=False)
class Fun(Object):
is_working_weekend = models.BooleanField(default=False)
is_kids_suitable = models.BooleanField(default=False)
class Other(Object):
is_working_weekend = models.BooleanField(default=False)
class Comment(models.Model):
object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
content = models.TextField()
rating = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return f"{self.content}"
views.py:
from django.shortcuts import render, redirect
from django.views import generic
from objects.models import Object, ProfileUser, Comment, Restaurant, SportFitness, CarService, BeautySalon, FastFood, CarWash, Fun, Other
from .forms import ObjectForm, CommentForm
from django.contrib import messages
from django.db.models import Avg
import sys, pdb
class AllObjects(generic.ListView):
queryset = Object.objects.all()
template_name = 'show_all_objects.html'
class UserObjectsView(generic.ListView):
template_name = 'user_objects.html'
def get_queryset(self):
user_id = self.kwargs['pk']
return Object.objects.filter(author_id = user_id)
def add_object(request):
if not request.user.is_authenticated:
messages.info(request, 'За да добавите нов Обект, трябва да сте регистриран потребител!')
return redirect('account_login')
form = ObjectForm(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.author = ProfileUser.objects.get(user=request.user)
obj.save()
messages.success(request, 'Успешно добавихте нов Обект, може да видите вашите обекти във вашия профил!')
return redirect('home')
context = {
'form': form
}
return render(request, "add_object.html", context)
def show_object(request, pk):
obj = Object.objects.get(id=5)
if request.method == 'POST':
user = request.user
author = ProfileUser.objects.get(user=user)
comment = Comment()
comment.object = obj
comment.author = author
comment.content = request.POST.get('content')
comment.rating = request.POST.get('rating')
comment.save()
form = CommentForm()
reviews_count = Comment.objects.filter(object_id=pk).count()
rating = Comment.objects.filter(object_id=pk).aggregate(Avg('rating'))['rating__avg']
context = {
'form': form,
'object': obj,
'reviews_count': reviews_count,
'rating': rating
}
return render(request, "show_object.html", context)
def show_all_objects(request, category):
categories = {'restaurants' : 'Restaurant', 'sportfitness' : 'SportFitness', 'carservice' : 'CarService', 'beautysalon' : 'BeautySalon', 'fastfood' : 'FastFood', 'carwash' : 'CarWash', 'fun' : 'Fun', 'other' : 'Other'}
objects = eval(categories[category]).objects.all()
context = {
'object_list': objects,
}
return render(request, 'show_all_objects.html', context)
Все было хорошо, пока мне не пришлось показывать объекты для каждой категории, как здесь (я использую рестораны вместо ресторана, потому что URL выглядит оченьлучше):
<a href="{% url 'show-all-objects' category='restaurants' %}" class="utf_category_small_box_part"> <i class="im im-icon-Chef"></i>
<h4>Ресторантии</h4>
<span>22</span>
</a>
<a href="{% url 'show-all-objects' category='sportfitness' %}" class="utf_category_small_box_part"> <i class="im im-icon-Dumbbell"></i>
<h4>Спортни и фитнес</h4>
<span>15</span>
</a>
Вы можете проверить функцию show_all_objects
, поэтому я сделал это с помощью eval()
:
categories = {'restaurants' : 'Restaurant', 'sportfitness' : 'SportFitness', 'carservice' : 'CarService', 'beautysalon' : 'BeautySalon', 'fastfood' : 'FastFood', 'carwash' : 'CarWash', 'fun' : 'Fun', 'other' : 'Other'}
objects = eval(categories[category]).objects.all()
Все было хорошо, но потом я снова столкнулся с этой проблемой. Когда я хочу показать объект с его функциями в show_object()
-методе (вы можете проверить это в коде выше), я могу получить объект, но не могу получить, например, restaurant
или car wash
и т. Д .:
def show_object(request, pk):
obj = Object.objects.get(id=5)
Теперь у меня есть объект, но я не могу получить точный объект. Я снова сталкиваюсь с той же проблемой, когда хочу показать разные формы для каждого типа объекта (например, рестораны должны иметь форму с флажками со своими функциями, форму для автомойки с флажками для ее функций и т. Д.).
PS: Основываясь на ответе @ Saawhat , он рекомендует мне использовать функцию eval()
в show_object()
, но я передаю все объекты в шаблоне, поэтому я не могу передать ему параметр типа param:
<div class="row">
{% for object in object_list %}
<div class="col-lg-12 col-md-12">
<div class="utf_listing_item-container list-layout"> <a href="{% url 'show-object' category='' pk=object.id%}" class="utf_listing_item">
<div class="utf_listing_item-image">
<img src="{% static 'core/images/utf_listing_item-01.jpg' %}" alt="">
<span class="like-icon"></span>
<span class="tag"><i class="im im-icon-Hotel"></i> Hotels</span>
<div class="utf_listing_prige_block utf_half_list">
<span class="utf_meta_listing_price"><i class="fa fa-tag"></i> $25 - $45</span>
<span class="utp_approve_item"><i class="utf_approve_listing"></i></span>
</div>
</div>
<div class="utf_listing_item_content">
<div class="utf_listing_item-inner">
<h3>{{ object.title }}</h3>
<span><i class="sl sl-icon-location"></i> {{ object.address }}</span>
<p>{{ object.content }}</p>
</div>
</div>
</a>
</div>
</div>
{% endfor %}
</div>
В этой строке:
<a href="{% url 'show-object' category='' pk=object.id%}"
Я не могу пройти категорию, потому что у меня ее нет