Mor*_*arm 3 python django django-2.2
我正在构建一个简单的Django应用,用于审查不同的对象(餐厅,汽车服务,洗车等)。
我开始使用该应用程序,但很快遇到了第一个问题。每个对象都有特征(但是每种类型的对象都有不同的特征)。
例如:
因此,我开始用ManyToMany表构建典型的数据库实现,但是随后我发现了Django Model Inheritance,因此可以在自己的APP中实现它,如您所见:
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"),
]
Run Code Online (Sandbox Code Playgroud)
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}"
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到我不得不显示每个类别的对象为止,像这样(我使用餐厅而不是餐厅,因为网址看起来要好得多):
<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>
Run Code Online (Sandbox Code Playgroud)
您可以检查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()
Run Code Online (Sandbox Code Playgroud)
很好,但随后我又遇到了这个问题。当我想在show_object()-method中显示具有其功能的对象时(可以在上面的代码中对其进行检查),我可以获取该对象,但是无法获取restaurant例如car wash等等。
def show_object(request, pk):
obj = Object.objects.get(id=5)
Run Code Online (Sandbox Code Playgroud)
现在我有了对象,但是我无法获得确切的对象。当我想为每种类型的对象显示不同的表单时,我再次遇到相同的问题(例如,餐厅的表单应具有其功能的复选框,洗车表单应具有其功能的复选框,等等)。
PS:基于@Saawhat的答案,他建议我eval()在show_object()函数中使用,但是我将模板中的所有对象都作为对象,因此我无法将类似类别的参数传递给它:
<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>
Run Code Online (Sandbox Code Playgroud)
该行:
<a href="{% url 'show-object' category='' pk=object.id%}"
Run Code Online (Sandbox Code Playgroud)
我无法通过类别,因为我没有一个
1:对模型使用继承时
class Meta:
abstract = True
Run Code Online (Sandbox Code Playgroud)
在您的基本模型中,这种Object情况下就不会创建自己的实例/表。因此,在这种情况下,您的模型将看起来像
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)
class Meta:
abstract = True
def __str__(self):
return f"{self.title}"
Run Code Online (Sandbox Code Playgroud)
另一方面,重命名Object为其他类似的BaseModel东西。
2:调用时,show_object传递模型的类别/名称并对其进行查询,例如:
Run Code Online (Sandbox Code Playgroud)obj = Object.objects.get(id=5) #Instead of this obj = eval(categories[category]).objects.get(pk=pk) # Do this
3:对于Comment模型,可以为每个模型添加一堆外键,也可以在Django中使用Generic Relation。
4:在显示表单时使用各自的模型而不是Object模型。无论如何,您都可以访问所有字段,因为您是继承自该字段。
我希望我已经回答了您所有的问题,如果没有让我知道。
更新:关于您不能从模板传递类别,在您的视图中也将类别传递给模板
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,
'category': category
}
return render(request, 'show_all_objects.html', context)
Run Code Online (Sandbox Code Playgroud)
现在,您可以访问category模板文件并将其传回。
| 归档时间: |
|
| 查看次数: |
225 次 |
| 最近记录: |