2

Vehicles というフォームがあり、ユーザーが完了するたびに、それぞれに一意の ID を割り当てようとしています。

class Vehicles(models.Model):
     id = models.DecimalField(primary_key=True, unique=True)

フォームを保存する前に、最後の vehicle-db-record に従って id フィールドに割り当てた初期値の後、競合状態 (2 つのフォームが同時に送信されている場合) を回避しようとしています。id のデータベースを再度クエリします。最後のレコードの。多かれ少なかれ、私はこのようにします:

def vehicle(request):
    vehicles= Vehicles.objects.all().order_by("-id")[0]
    id = vehicles.id+1

    if request.method == 'POST':
        form = VehiclesForm(data=request.POST)

        if form.is_valid():
            vehicles= Vehicles.objects.all().order_by("-id")[0]
            id = vehicles.id+1
            temp = form.save(new_veh_id=id)
            return render_to_response('success.html', locals(), context_instance= RequestContext(request))
    else:
        form = VehiclesForm(initial={'id': id})
    return render_to_response('insertVehicle.html', locals(), context_instance= RequestContext(request))

フォームでは、save メソッドをオーバーライドします。

    def save(self, *args, **kwargs):
        commit = kwargs.pop('commit', True)
        new_veh_id = kwargs.pop('new_veh_id', None)
        instance = super(VehiclesForm, self).save(*args, commit = False, **kwargs)

        if id is not None: instance.id = new_veh_id
        if commit:
            instance.save()
        return instance

しかし、is_valid はフォーム error:vehicles with this id already exists で false を返します。私は別のモデルとフォーム (これらと同じフィールド) でこのプラクティスを正確に使用します。これは魅力のように機能し、フォームは同じ ID にもかかわらず検証に合格し、最後に送信されたフォームで変更されます。誰かがこれについて私を助けたり、この機能を実現するためのより良い解決策を提案したりできますか? 私がしていることは、おそらくどういうわけか「カスタム」です。

編集:これも試しましたが、 is_valid が再び失敗します

    def clean(self):
        cleaned_data = super(VehiclesForm, self).clean()
        id = unicode(self.cleaned_data.get('id'))

        vehicles= Vehicles.objects.all().order_by("-id")[0]
        id = vehicles.id+1
        cleaned_data[id] = id

        return cleaned_data
4

1 に答える 1

1

トランザクションが終了するまで行をロックするselect_for_updateが必要だと思います。多くの行で動作するように指定されていますが、filterクエリが 1 つのオブジェクトのみを返すようにすることで、1 行だけをロックすることができます。

于 2012-09-14T13:35:26.783 に答える