相关疑难解决方法(0)

处理model.save()中的竞争条件

如何在模型的save()方法中处理可能的竞争条件?

例如,以下示例实现具有相关项的有序列表的模型.创建新项目时,当前列表大小用作其位置.

据我所知,如果同时创建多个项目,这可能会出错.

class OrderedList(models.Model):
    # ....
    @property
    def item_count(self):
        return self.item_set.count()

class Item(models.Model):
    # ...
    name   = models.CharField(max_length=100)
    parent = models.ForeignKey(OrderedList)
    position = models.IntegerField()
    class Meta:
        unique_together = (('parent','position'), ('parent', 'name'))

    def save(self, *args, **kwargs):
        if not self.id:
            # use item count as next position number
            self.position = parent.item_count
        super(Item, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我遇到过@transactions.commit_on_success()但这似乎只适用于视图.即使它确实适用于模型方法,我仍然不知道如何正确处理失败的事务.

我当前正在处理它,但它感觉更像是一个黑客而不是一个解决方案

def save(self, *args, **kwargs):
    while not self.id:
        try:
            self.position = self.parent.item_count
            super(Item, self).save(*args, **kwargs)
        except IntegrityError:
            # chill out, then …
Run Code Online (Sandbox Code Playgroud)

python database django django-models race-condition

17
推荐指数
1
解决办法
3663
查看次数

Django:如何检查用户名是否已存在

我不是Django的高级用户.我在网上看到了很多不同的方法,但它们都是针对修改过的模型,或者太复杂,我无法理解.我正在重复使用UserCreationForm我的MyRegistrationForm

class MyRegistrationForm(UserCreationForm):

    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

    def save(self, commit=True):
        user = super(MyRegistrationForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        user.set_password(self.cleaned_data["password1"])

        if commit:
            user.save()

        return user
Run Code Online (Sandbox Code Playgroud)

我很难理解或找到一种方法来检查用户输入的用户名是否已被使用.所以我只是用它来重定向到html,它说错误的用户名或密码不匹配:

def register_user(request):
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save()

            return HttpResponseRedirect('/accounts/register_success')
        else:
            return render_to_response('invalid_reg.html')


    args = {}
    args.update(csrf(request))

    args['form'] = MyRegistrationForm()
    print args
    return render_to_response('register.html', args)
Run Code Online (Sandbox Code Playgroud)

这是我的注册模板(如果需要):

{% extends "base.html" %}

{% block content %}

<section>
<h2 style="text-align: center">Register</h2>
<form …
Run Code Online (Sandbox Code Playgroud)

python django validation registration username

12
推荐指数
2
解决办法
2万
查看次数

Django 1.6中的ATOMIC_REQUEST和事务

给出以下代码:

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()
Run Code Online (Sandbox Code Playgroud)

根据我对Django 1.6中事务的理解,如果do_stuff抛出异常,比如说IntegrityError,那么事务将被正确回滚.但是,由于Django本身正在调用视图,因此不会阻止IntegrityError上升调用堆栈并导致HTTP 500错误吗?让我们假设这不是我们想要的,因为我们希望优雅地处理错误,但仍然获得回滚功能.

所以我想明显的想法是好的,不要这样做,transaction.atomic用作包含在try中的上下文管理器,除了像这里的例子一样的块:

try:
    with transaction.atomic():
        generate_relationships()
except IntegrityError:
    handle_exception()
Run Code Online (Sandbox Code Playgroud)

精细.但是如果你想通过在db配置中设置ATOMIC_REQUEST = True来使用每个HTTP请求的事务功能,这意味着django实际上只是将transaction.atomic装饰添加到你的视图中,这将不会捕获任何异常.ATOMIC_REQUEST如何有用?为什么你想让你的数据库错误一直传播给用户?

所以我的问题是.

  1. 我在这里缺少什么或者我的理解是否正确?
  2. 如果我是正确的,使用ATOMIC_REQUEST的用例是什么?我urls.hadler500是否应该写一个或者我应该实现一些中间件来捕获错误?

python django transactions

7
推荐指数
1
解决办法
1885
查看次数