Я тоже сталкивался с этим при создании приложения на основе CRUD. Я не уверен, что есть лучший способ, но в итоге я использовал exists()
, чтобы проверить, существует ли запись ...
Вы можете использовать get_or_create в области видимости is_valid (), однако вам необходимо проверить, существует ли обзор, прежде чем отображать вашу форму, чтобы загрузить данные экземпляра в форму в случае, если обзор уже существует.
Ваш models.py может выглядеть так:
from django.db import models
from django.contrib.auth.models import User
class Wine(models.Model):
name = models.CharField()
class Review(models.Model):
wine = models.ForeignKey(Wine)
user = models.ForeignKey(User)
like = models.BooleanField(null=True, blank=True) # if null, unrated
Ваш файл forms.py может выглядеть следующим образом:
from django import forms
class WineReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = ['like',] # excludes the user and wine field from the form
Использование get_or_create позволит вам сделать это, если используется так:
@login_required
def wine_review_page(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
review, created = Review.objects.get_or_create(user=request.user, wine=wine)
if request.method == 'POST':
form = WineReviewForm(request.POST, instance=review)
if form.is_valid():
form.save()
return HttpResponseRedirect('/detail/%s/' % wine_id )
else:
form = WineReviewForm(instance=review)
variables = RequestContext(request, {'form': form, 'wine': wine })
return render_to_response('wine_review_page.html', variables)
Выполнение создает обзор, просто посещая страницу, и требует, чтобы другая информация либо имела значение по умолчанию, либо оставалась пустой на уровне модели.
С exists()
вы получите два удара в дБ, если обзор существует, однако вы не создадите объект, если пользователь не отправит действительную форму:
@login_required
def wine_review_page(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
review = None
if Review.objects.filter(user=request.user, wine=wine).exists():
review = Review.objects.get(user=request.user, wine=wine)
if request.method == 'POST':
form = WineReviewForm(request.POST, instance=review)
if form.is_valid():
form.save()
return HttpResponseRedirect('/detail/%s/' % wine_id )
else:
form = WineReviewForm(instance=review)
variables = RequestContext(request, {'form': form, 'wine': wine })
return render_to_response('wine_review_page.html', variables)
Я использовал exists()
, но я думаю, что это может быть лучше?
try:
review = Review.objects.get(user=request.user, wine=wine)
except Review.DoesNotExist:
review = None
Надеюсь, кто-то с большим опытом присоединится.
Edit:
Вот довольно старый пост Даниэля Роземана Blog
. Я не знаю, применимо ли оно до сих пор, но может иметь отношение к вашему вопросу.