问题
Searched everywhere but couldn't find anything even though it feels so simple.
So basically i have two classes in my models.py
class Restaurant(models.Model):
restaurant_title = models.CharField(max_length=30)
location = CountryField(null=True, blank_label='(select country)')
first_purchase_discount = models.BooleanField(default=False)
updated = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=30, unique=True)
def save (self, *args, **kwargs):
self.slug = slugify(self.restaurant_title)
super(Restaurant, self).save(*args, **kwargs)
def __str__(self):
return self.restaurant_title
class Pizza(models.Model):
pizza_title = models.CharField(max_length=20)
restaurants = models.ManyToManyField('Restaurant', blank=True)
slug = models.SlugField(max_length=20, unique=True)
def save (self, *args, **kwargs):
self.slug = slugify(self.pizza_title)
super(pizza, self).save(*args, **kwargs)
def __str__(self):
return self.pizza_title
now what i did, was register the models in my admin.py
.
There i created let's say Restaurant Toni and Restaurant Pappo.
On the other hand i created the Pizzas: A, B, C and D.
Through the ManyToMany relationship i connected Pizza A,B and C to Toni
and B, C and D to Pappo
.
In my views.py
i created a Listview which functions as the Homepage to show where all the Restaurants are being displayed through:
restaurants = Restaurant.objects.all()
To list the Pizzas i created a DetailView. I've created a link in my restaurant_list.html (which functions as the homepage) to access the Pizzas
{% for restaurant in restaurants %}
<h2><a href="{% url 'pizza_detail' restaurant.slug %}">{{ restaurant.restaurant_title }}</a></h2>
{% endfor%}
I get the restaurants and each links me to the the Pizzas i associated them to or at least i wish that to happen.
here a clear view at my views.py
class RestaurantListView(ListView):
model = Restaurant
def get_context_data(self, **kwargs):
context = super(RestaurantListView, self).get_context_data(**kwargs)
return context
def home(request):
template = 'restaurant/restaurant_list.html'
restaurants = Restaurant.objects.all()
context = {
'restaurants': restaurants
}
return render(request, template, context)
class PizzaDetailView(DetailView):
model = Pizza
def get_context_data(self, **kwargs):
context = super(ShopDetailView, self).get_context_data(**kwargs)
return context
def pizza_detail(request, slug):
template = 'restaurant/pizza_detail.html'
pizzas = Pizza.objects.all()
context = {
'pizzas': pizzas,
}
return render(request, template, context)
Due to the pizzas = Pizza.objects.all() i obviously get all the Pizzas. But of course i only want the associated ones which means when i click on Toni, i want to see Pizze A,B and C and the related Pizzas for Pappo when i click on "it's" link.
Do i have to change pizzas = Pizza.objects.all()
or the for loop
in my pizza_detail.html
, that for now looks like this?
{% for pizza in pizzas %}
<h1>{{pizza.pizza_title}}</h1>
{% endfor%}
Hope you get my point.
Ps: can you also tell me how to also show the restaurant's name in my pizza_detail.html through which i clicked the link. Thanks alot <3
EDIT
home.urls.py
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^users/', include('django.contrib.auth.urls')),
url(r'^', include('restaurant.urls')),
]
restaurant.urls.py
urlpatterns = [
path('', home, name='restaurant_list'),
path('restaurant/<slug:slug>/', pizza_detail, name='pizza_detail')
]
回答1:
If you want the Pizzas related to particular restaurant when clicked on them, you should also use the Restaurant
model to filter your data
So in views.py
def pizza_detail(request, slug):
template = 'restaurant/pizza_detail.html'
restaurant = Restaurant.objects.get(slug=slug)
pizzas = Pizza.objects.filter(restaurants__in=[restaurant])
context = {
'pizzas': pizzas,
'restaurant': restaurant
}
return render(request, template, context)
and in pizza_detail.html
<h1>Restaurant : {{ restaurant.restaurant_title }}</h1>
{% for pizza in pizzas %}
<h3>{{pizza.pizza_title}}</h3>
{% endfor%}
NOTE : The restaurants__in
lookup takes only iterables, hence particular Restaurant
object passed as list
.
回答2:
Pizza and Restaurant is ManytoMany relation. You can use prefetch_related() for looking pizzas from Restaurant model or vice versa
example: pizzas = Pizza.objects.all().prefetch_related('restaurants')
if you want show restaurant's name in pizza_detail.html. Use example query and change html like this.
{% for pizza in pizzas %}
{% for restaurant in pizza.restaurants %}
{{restaurant.restaurant_title}}
{% endfor%}
{% endfor%}
来源:https://stackoverflow.com/questions/51144387/django-manytomany-show-related-objects