使用Django 1.2我正在制作葡萄酒评论网站。用户应该只能查看一次葡萄酒,但应该能够返回并重新检查葡萄酒而不会产生错误。
使用get_or_create方法似乎是最合理的解决方案,但我遇到了实现它的各种问题。搜索我发现这篇看起来很有前途的文章: Correct way to use get_or_create?
当然还有关于它的django文档: http://docs.djangoproject.com/en/1.2/ref/models/querysets/#get-or-create
但似乎没有回答我的问题。这是我的代码:
Views.py
@login_required
def wine_review_page(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
if request.method == 'POST':
form = WineReviewForm(request.POST)
if form.is_valid():
review, created = Review.objects.get_or_create(
user = request.user,
wine = wine,
like_dislike = form.cleaned_data['like_dislike'],
...
)
variables = RequestContext(request, {
'wine': wine
})
review.save()
return HttpResponseRedirect(
'/detail/%s/' % wine_id
)
else:
form = WineReviewForm()
variables = RequestContext(request, {
'form': form,
'wine': wine
})
return render_to_response('wine_review_page.html', variables)
Models.py
class Review(models.Model):
wine = models.ForeignKey(Wine, unique=True)
user = models.ForeignKey(User, unique=True)
like_dislike = models.CharField(max_length=7, unique=True)
...
如果我理解如何正确使用get_or_create,因为我不匹配所有值like_dislike等...然后django认为它是唯一的。我尝试删除其他表单参数,但随后它们不会与post请求一起提交。
建议将不胜感激。
答案 0 :(得分:0)
在制作基于CRUD的应用时,我也遇到过这种情况。我不确定是否有更好的方法,但我最终做的方法是使用exists()
来检查条目是否存在。
您可以在is_valid()范围内使用get_or_create,但是,在显示表单之前,您需要检查审核是否存在,以便在审核已存在的情况下将实例数据加载到表单中。
您的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()
,如果审核存在,则会获得两次db命中,但是除非用户提交有效的表单,否则不会创建对象:
@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
希望有经验的人会参与进来。
修改强>
丹尼尔罗斯曼的Blog
这是一篇相当古老的帖子。我不知道它是否仍然适用,但可能与您的问题有关。