Я пытаюсь создать приложение "рейтинг ресторана" на Django 3. Я настроил следующие модели:
# Table storing the different restaurants
class Restaurant(models.Model):
restaurant_name = models.CharField(max_length=200, unique=True)
restaurant_address = models.CharField(max_length=200)
restaurant_street_number = models.CharField(max_length=10)
restaurant_city = models.CharField(max_length=200)
restaurant_cuisine_type = models.CharField(max_length=200)
def __str__(self):
return self.restaurant_name + ' - ' + self.restaurant_city
class UserReview(models.Model):
# Defining the possible grades
Grade_1 = 1
Grade_2 = 2
Grade_3 = 3
Grade_4 = 4
Grade_5 = 5
# All those grades will sit under Review_Grade to appear in choices
Review_Grade = (
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5')
)
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
user_review_grade = models.IntegerField(default=None, choices=Review_Grade) # default=None pour eviter d'avoir un bouton vide sur ma template
user_review_comment = models.CharField(max_length=1500)
def get_absolute_url(self):
return reverse('restaurants:reviews', args=[self.id])
Это форма, которую я использую:
# Form for user reviews per restaurant
class UserReviewForm(forms.ModelForm):
class Meta:
model = UserReview
# restaurant = forms.ModelChoiceField(queryset=Restaurant.objects.filter(pk=id))
fields = [
'restaurant',
'user_review_grade',
'user_review_comment'
]
widgets = {
'restaurant': forms.HiddenInput,
'user_review_grade': forms.RadioSelect,
'user_review_comment': forms.Textarea
}
labels = {
'user_review_grade': 'Chose a satisfaction level:',
'user_review_comment': 'And write your comments:'
}
Вот мои URL:
app_name = 'restaurants'
urlpatterns = [
# ex: /restaurants/
path('', views.index, name='index'),
# ex: /restaurants/15
path('<int:restaurant_id>/', views.details, name='details'),
# ex: /restaurants/test
path('<int:restaurant_id>/test', views.Test.as_view(), name='test')
]
Шаблон:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TEST</title>
</head>
<body>
<h1>Write a review for this restaurant:</h1>
<form method="post">
{% csrf_token %}
<input type="Hidden" name="restaurant" value="{{restaurant.restaurant_id}}">
{{ form.as_p }}
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>
И, наконец, мое мнение:
# Test class to be renamed posts reviews as it should
class Test (CreateView):
template_name = 'restaurants/TEST.html'
form_class = UserReviewForm
# Get the initial information needed for the form to function: restaurant field
def get_initial(self, restaurant_id, *args, **kwargs):
initial = super(Test, self).get_initial(**kwargs)
initial['restaurant'] = 9
return initial()
# Post the data into the DB
def post(self, request, *args, **kwargs):
form = UserReviewForm(request.POST)
if form.is_valid():
review = form.save()
print(review) # Print so I cna see in cmd prompt that something posts as it should
review.save()
return render(request, 'restaurants/reviews.html', {'form': form})
У меня возникла проблема, когда Я определяю initial как целое число (скажем, 9 - так как я проверял, действительно ли моя форма публиковала), он без проблем публикует обзор в БД для ресторана с id = 9. Однако я не могу его получить restaurant_id автоматически заполняется в зависимости от того, какую страницу ресторана мы посещаем.
Я попробовал следующее, а также несколько других «хитростей», найденных здесь и там, но, похоже, ничего не помогло ...
# Test class to be renamed later IF it works...
class Test (CreateView):
template_name = 'restaurants/TEST.html'
form_class = UserReviewForm
# Get the initial information needed for the form to function: restaurant field
def get_initial(self, restaurant_id, *args, **kwargs):
restaurant = get_object_or_404(Restaurant, pk=restaurant_id)
initial = super(Test, self).get_initial(**kwargs)
initial['restaurant'] = self.request.restaurant.pk
return initial()
# Post the data into the DB
def post(self, request, *args, **kwargs):
form = UserReviewForm(request.POST)
if form.is_valid():
review = form.save()
print(review) # Print so I cna see in cmd prompt that something posts as it should
review.save()
return render(request, 'restaurants/reviews.html', {'form': form})
Буду признателен за любую помощь, чтобы указать мне правильное направление:)