首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >django创建自定义id def save()

django创建自定义id def save()
EN

Stack Overflow用户
提问于 2022-09-08 01:01:01
回答 2查看 40关注 0票数 0

我有一个postgres函数,它所做的是当我保存一个项目时,它创建一个test2021-20221-1. cl_itemid然后,在表clearing_office中,列office_serial增量+1,因此保存的下一项将是office_serial

代码语言:javascript
运行
复制
SELECT CONCAT(f_office_id,f_sy,f_sem,'-',office_serial) INTO office_lastnumber from curriculum.clearing_office
    where office_id=f_office_id;
    
UPDATE curriculum.clearing_office SET office_serial =office_serial+1 where office_id=f_office_id;


{
    "studid": "4321-4321",
    "office": "test",
    "sem": "1",
    "sy": "2021-2022",
}

是否可以通过Django模型来创建这个问题,或者可能是解决这个问题的另一个解决方案?

这是我的模型课

代码语言:javascript
运行
复制
class Item(models.Model):
    cl_itemid = models.CharField(primary_key=True, max_length=20)
    studid = models.CharField(max_length=9, blank=True, null=True)
    office = models.ForeignKey('ClearingOffice', models.DO_NOTHING, blank=True, null=True)
    sem = models.CharField(max_length=1, blank=True, null=True)
    sy = models.CharField(max_length=9, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'item'
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-08 01:42:43

一个简单的方法可能是在python中使用default函数。

代码语言:javascript
运行
复制
def get_default_id():
    last_id = Item.objects.last().cl_itemid
    split_id = last_id.split('-')
    split_id[-1] = str(int(split_id[-1])+1)
    new_id = '-'.join(split_id)
    return new_id

class Item(models.Model):
    cl_itemid = models.CharField(..., default=get_default_id)

类似的方法在这个答案中描述。

在这种方法中,您需要预见的一件事是,当同时创建两个或多个新对象(即,两个新对象同时运行默认函数,可能会导致两个新对象返回相同的ID )时,可能会出现争用条件。如果您认为事务或重试将是应用程序中的一个问题,则可以解决该问题。

一种健壮的方法是创建您自己的模型字段并在内部处理该领域的实现。这将允许您以不同的方式实现解决方案,这取决于DB方言,并让它在没有竞争条件问题的情况下跨DB实现工作。

票数 0
EN

Stack Overflow用户

发布于 2022-09-08 01:41:50

我在很多模特身上都这样做,有点不同。我只是在自定义保存方法上使用窗体和tac。

我没有使用过非托管模型,但从我从google上看到的情况来看,这并没有什么不同。

表格(forms.py)

代码语言:javascript
运行
复制
class ItemForm(forms.ModelForm):
    class Meta:
        model = Item
        fields = (
            'cl_itemid',
            'studid',
            'office',
            'sem',
            'sy',
            )

    def __init__(self,  *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        obj = super(ItemForm, self).save(commit=False)

        if not self.instance:
            # you only want it hitting this if it's new!
            from datetime import datetime
            now = datetime.now()

            count = Item.objects.all().count()
            # you could also just grab the last
            #   + chop the id to get the last number

            obj.cl_itemid = 'test{0}-{1}'.format(now.strftime('%Y-%m%d%y'), count)

        if commit:
            obj.save()

您甚至可以在实际的保存方法super(ItemForm, self).save(commit=False)之前对其进行测试,甚至可以执行一个cl_itemid。我将在我的终端进行一些测试,看看这是否是一个选项,可能会更干净。

用法

视图(职位)

代码语言:javascript
运行
复制
def ItemFormView(request):
    from app.forms import ItemForm
    if request.method == "POST":
        # this is just for edits
        itemObj = Item.objects.get(pk=request.POST.get('itemid')) if request.POST.get('itemid') else None

        form = ItemForm(request.POST or None, instance=itemObj)
        if form.is_valid():
            obj = form.save()
            return HttpResponseRedirect(reverse('sucesspage')

        print(form.errors)
        print(form.errors.as_data())
        # this will render the page with the errors
        data = {'form': form}
    else:
        data = {'form': ItemForm()}
    return render(request, 'itemform.html', data)

代码语言:javascript
运行
复制
f = ItemForm(data={'office':'test', 'sem':'1', 'etc':'etc'})
if f.is_valid():
    o = f.save()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73642741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档