最多Django / pythonic的创建或覆盖记录的方式是什么? [英] Whats the most Django/pythonic way to create or overwrite a record?

查看:116
本文介绍了最多Django / pythonic的创建或覆盖记录的方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Django 1.2我正在做一个葡萄酒评论网站。用户应该只能检查一次葡萄酒,但应该可以回去并重新检查葡萄酒,而不会出现错误。

Working with Django 1.2 I am making a wine review site. A user should only be able to review each wine once, but should be able to go back and re-review a wine without raising an error.

使用get_or_create方法似乎最合理的解决方案,但我一直在执行它的各种问题。搜索我发现这篇文章看起来很有希望:
正确的方法来使用get_or_create ?

Using the get_or_create method seems the most rational solution but I have been running into various problems implementing it. Searching I found this article which looked promising: Correct way to use get_or_create?

当然还有django文档:
http://docs.djangoproject.com/en/1.2/ref/models/querysets/#get-or-create

and of course the django documentation on it: http://docs.djangoproject.com/en/1.2/ref/models/querysets/#get-or-create

但似乎没有回答我的问题。这是我的代码:

But didn't seem to answer my question. Here is my code:

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 p>

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 ,因为我不匹配所有的值,如__dislike等等,那么django会觉得它是独一无二的。我尝试删除其他表单参数,但是后来没有提交发布请求。

If I understand how to use get_or_create correctly, since I am not matching on all the values like_dislike, etc... then django perceives it to be unique. I tried removing the other form parameters, but then they are not submitted with the post request.

建议将不胜感激。

推荐答案

在制作基于CRUD的应用程序时,我也遇到了这个问题。我不知道是否有更好的方法,但是我最终的做法是使用 exists() 来检查是否存在条目。

I came across this too when making a CRUD based app. I'm not sure if there's a better way but the way I ended up getting doing was using a exists() to check if an entry ... exists.

您可以在is_valid()范围内使用get_or_create,但是在显示表单之前,您需要检查是否存在审阅,以便在审核已经存在的情况下将实例数据加载到表单中。

You can use get_or_create within the is_valid() scope, however, you need to check if the review exists before displaying your form in order to load instance data into the form in the case that the review already exists.

您的models.py可能如下所示:

Your models.py might look like this:

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可能如下所示:

Your forms.py might look like this:

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可以让您如此使用:

Using get_or_create will let you do this if used like so:

@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) 

只需访问该页面即可创建评论,并要求其他信息默认或允许在模型级别为空。

Doing creates a review just by visiting the page and requires that the other information either have a default or are allowed to be blank at the model level.

使用 exists(),如果审核存在,您将得到两个db命中,但是除非用户提交有效的表单,否则您不创建对象:

With exists(), you get two db hits if the review exists, however you don't create an object unless the user submits a valid form:

@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()我认为这可能会更好?

I used exists() but I think that this might be better?

try:
    review = Review.objects.get(user=request.user, wine=wine)
except Review.DoesNotExist:
    review = None

充满希望有更多经验的人将会进入。

Hopefully someone with more experience will chime in.

编辑:

以下是Daniel Roseman的 博客 。我不知道它是否仍然适用,但可能与您的问题有关。

Here is a fairly old post from Daniel Roseman's Blog. I don't know if it is still applicable, but might be relevant to your question.

这篇关于最多Django / pythonic的创建或覆盖记录的方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆