标签: django-orm

Django:UpdateView - 调度:减少查询数量

我有一个产品模型、公司模型的外键、用户的单键。

我重写调度(方法)来检查用户是否有权编辑对象(产品)。

我正在尝试优化对数据库的查询,因为其中一些是重复的。

def dispatch(self, request, *args, **kwargs):
    obj = self.get_object()
    if obj.company.user != request.user:
        raise PermissionDenied
    else:
        print('ok')
        return super().dispatch(request, *args, *kwargs)
Run Code Online (Sandbox Code Playgroud)

查询产品

obj = self.get_object() 
Run Code Online (Sandbox Code Playgroud)

向公司查询和向用户查询两次

if obj.company.user != request.user:
Run Code Online (Sandbox Code Playgroud)

再次查询产品

 return super().dispatch(request, *args, *kwargs)
Run Code Online (Sandbox Code Playgroud)

如何优化和删除重复查询?

django django-orm django-class-based-views

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

Django 保存到数据库:TypeError: int() 参数必须是字符串、类似字节的对象或数字,而不是“元组”

我在将数据保存到数据库中的 def 中遇到了问题。

    @staticmethod
    def _save(account, proxy,
              proxy_provider_id, period,
              country, start_date,
              price, meta,
              account_type, ip):
        try:
            period = int(period)
            end_date = start_date + timedelta(days=period)
            prx = Proxy()
            prx.account = account
            prx.proxy = proxy
            prx.proxy_provider_id = proxy_provider_id
            prx.period = period,
            prx.country = country,
            prx.start_date = start_date
            prx.end_date = end_date
            prx.price = price
            prx.meta = meta
            prx.ip = ip
            print('\n')
            print('Save proxy {}'.format(prx))
            print('account: {} type {}'.format(account, type(account)))
            print('proxy: {} type {}'.format(proxy, type(proxy)))
            print('proxy id: {} type {}'.format(proxy_provider_id, type(proxy_provider_id)))
            print('country: {} type …
Run Code Online (Sandbox Code Playgroud)

python django django-orm python-3.x

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

在 Django 中使用用户输入构建动态查询

我有一个大模型,其中存储 10 个基于文本的值和 10 个数值。像这样的东西:

class Dataset(models.Model):
    text_field_1 = models.CharField(max_length=255)
    .
    .
    .
    text_field_10 = models.CharField(max_length=255)

    number_field_1 = models.IntegerField()
    .
    .
    .
    number_field_10 = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

现在,我想做的是通过将对象传递给视图,为用户提供一种使用这些字段来过滤和排序数据集的方法。希望下面的示例展示了我想要做的事情:

obj = {
    "filters" : [
        "text_field_1='vaccines'",
        "number_field_5__gte=1000",
    ],
    "order_by" : "text_field_3, -number_field_7",
    "excludes" : [],
}

generate_query(obj) # Dataset.objects.filter(text_field_1='vaccines', number_field_5__gte=1000).order_by('text_field_3', '-number_field_7')
Run Code Online (Sandbox Code Playgroud)

因此,通过调用generate_query(obj),我们可以获取注释中的查询集。现在,由于该模型的性质,我不可能通过考虑过滤器、订单和排除的每种可能的组合来手动执行此操作。

实现这一点的最佳、最安全的方法是什么?我唯一想到的是创建一个大字符串,然后使用execoreval执行该字符串。

python django django-orm

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

在原子块内调用的“select_for_update”仍然是 TransactionManagementError

代码一击

@transaction.atomic
def cancel_one(o_id):
    order= Order.objects.select_for_update().get(id=o_id)
Run Code Online (Sandbox Code Playgroud)

加注

TransactionManagementError('select_for_update 不能在事务之外使用。')

django.db.transaction.TransactionManagementError: select_for_update 不能在事务之外使用。

我已经检查过我的代码是否在交易中 transaction.get_connection().in_atomic_block.

它出现在交易中,但仍然引发

错误:django.db.transaction.TransactionManagementError:select_for_update 不能在事务之外使用。

我的代码:

# Step1
def cancel_one(o_id):
   print("DO")
   cxn = transaction.get_connection()
   if cxn.in_atomic_block:
       print("We're inside a transaction!")
   order= Order.objects.select_for_update().get(id=o_id)

# Step2
@transaction.atomic
def cancel_one(o_id):
   print("DO")
   cxn = transaction.get_connection()
   if cxn.in_atomic_block:
       print("We're inside a transaction!")
   order= Order.objects.select_for_update().get(id=o_id)
Run Code Online (Sandbox Code Playgroud)

代码结果

# Step1
-----------------------
DO
-----------------------

# Step2
-----------------------
DO
"We're inside a transaction!"
-----------------------
Run Code Online (Sandbox Code Playgroud)

django django-orm

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

如何聚合基于两列的计算平均值?

我想编写一个 Django 查询来计算表中所有行的平均值。我的模型看起来像

class StatByDow(models.Model):
    total_score = models.DecimalField(default=0, max_digits=12, decimal_places=2)
    num_articles = models.IntegerField(default=0)
    day_of_week = IntegerField(
        null=True,
        validators=[
            MaxValueValidator(6),
            MinValueValidator(0)
        ]
    )
Run Code Online (Sandbox Code Playgroud)

我尝试像这样计算平均值

everything_avg = StatByDow.objects.all().aggregate(Avg(Func(F('total_score') / F('num_articles'))))
Run Code Online (Sandbox Code Playgroud)

但这会导致错误

  File "/Users/davea/Documents/workspace/mainsite_project/venv/lib/python3.7/site-packages/django/db/models/query.py", line 362, in aggregate
    raise TypeError("Complex aggregates require an alias")
TypeError: Complex aggregates require an alias
Run Code Online (Sandbox Code Playgroud)

计算平均值的正确方法是什么?

python django average django-orm

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

如何在 Django 中使 m2m_changed 信号原子化?

我的项目中有以下模型:

class Topping(models.Model):
    name = models.CharField(max_length=255)

class Pizza(models.Model):
    name = models.CharField(max_length=255)
    toppings = models.ManyToManyField(Topping, blank=True)

    def save(self, *args, **kwargs):
        print('Saving...')
        if self.pk:
            for topping in self.toppings.all():
                print(topping.name)

        super(Pizza, self).save(*args, **kwargs)

def toppings_changed(sender, instance, **kwargs):
    instance.save()

m2m_changed.connect(toppings_changed, sender=Pizza.toppings.through)
Run Code Online (Sandbox Code Playgroud)

基本上,每当toppings发生变化时,都会触发信号。信号所做的只是调用Pizza对象的 save 方法。无论如何,假设我有三个对象:

pizza = Pizza.objects.get(pk=1) # Number of toppings is 0
topping1 = Topping.objects.get(pk=1)
topping2 = Topping.objects.get(pk=2)
Run Code Online (Sandbox Code Playgroud)

现在,我想将这两种配料添加到我的披萨中。我使用以下代码执行此操作:

pizza = Pizza.objects.get(pk=1)
pizza.toppings.set([1, 2])
Run Code Online (Sandbox Code Playgroud)

配料设置正确,但是,披萨的 save 方法被调用两次,因为 m2m_changed 信号被调用两次,因为发生了两次更改。在提交所有更改后,如何才能仅调用一次?为了澄清,我希望添加两种配料,但我只想在所有更改结束时触发一次信号。谢谢你的帮助。

django many-to-many django-models django-orm

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

Django ORM concat 关联行(通过 ORM 进行字符串连接?)

两个简单的模型:

class Thread(models.Model):
    pass

class Message(models.Model):
    thread = models.ForeignKey(Thread, related_name='messages')
Run Code Online (Sandbox Code Playgroud)

可以做这样的事情吗?

>>> thread = Thread.objects.create()

>>> Message.objects.create(thread=thread, content='One')
>>> Message.objects.create(thread=thread, content='Two')
>>> Message.objects.create(thread=thread, content='Three')

>>> t = Thread.objects.annotate(
        message_content=MySuperConcat('messages__content')).first()
>>> t.messages_content

OneTwoThree
Run Code Online (Sandbox Code Playgroud)

似乎 Django 的 Concat 无法做到这一点,现在我不确定是否可以实现所需的行为。

注意:PostgreSQL 9.5 和 Django 1.11。

django django-orm

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

即使在 django 和discord.py 中使用sync_to_async 后也出现 SynchronousOnlyOperation 错误

我正在尝试为 Django 网站制作一个不和谐的机器人。在实现的时候我发现Django数据库不允许异步操作,我们必须使用线程或sync_to_async.

我使用过sync_to_async并且似乎有效。但后来我遇到了一个问题,我什至无法弄清楚它出了什么问题以及那里发生了什么。

谁能解释我在那里做错了什么以及那里发生了什么?

@sync_to_async
def get_customer(id):
    try:
        return Customer.objects.get(discord_id=id)
    except:
        return None
#------

@bot.command()
async def categories(ctx):
    customer = await get_customer(ctx.author.id) #this line of code works well
    categories = await sync_to_async(Category.objects.all().filter)(customer=customer)
    #categories = await sync_to_async(Category.objects.filter)(customer=customer)#I tried this also, didn't work
    print(categories) #problem is in the line
    embed = Embed(title='', description="{}".format('\n'.join([ x.name for x in categories])))
    await ctx.send(embed=embed)
Run Code Online (Sandbox Code Playgroud)

我收到的回溯错误是:

Running bot
Ignoring exception in command categories:
Traceback (most recent call last):
  File "/Users/rhidwan/Desktop/personal_transaction/venv/lib/python3.7/site-packages/discord/ext/commands/core.py", line 83, …
Run Code Online (Sandbox Code Playgroud)

python django django-orm python-asyncio discord.py

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

Django - 查询每个不同状态的计数

我有一个ModelModel.status字段的模型。该status字段可以是值draftactivecancelled

是否可以根据对象的状态获取所有对象的计数?我更愿意在一个查询中做到这一点,而不是这样:

Model.objects.filter(status='draft').count()
Model.objects.filter(status='active').count()
Model.objects.filter(status='cancelled').count()
Run Code Online (Sandbox Code Playgroud)

我认为这aggregate会有所帮助。

django postgresql django-orm django-queryset django-aggregation

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

Django 中的查询性能优化

我正在 django 中创建一个博客网站,在为特定博客文章创建页面时,我在使用 ORM 查询数据时遇到了问题。

我有一个 Post 模型,它与另一个模型评论相关,其中所有评论都被捕获。评论模型有以下字段 ->

class Comment(models.Model):
    comment = models.TextField(null=True)
    Created_date = models.DateTimeField(auto_now_add=True)
    Updated_date = models.DateTimeField(auto_now=True)
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments_post')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments_user')

    def __str__(self):
        return self.comment
Run Code Online (Sandbox Code Playgroud)

现在,在查询单个博客文章时,可能有 N 条评论,并且对于每个评论,都会分配一个撰写该评论的用户。所以我想找到每个评论的用户详细信息,例如(姓名、电子邮件或电话号码)。

我执行的查询是 ->

post = Post.objects.select_related().prefetch_related('images_set','comments_post').get(id=post_id)
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试使用{{comment.user.email}}该帖子时,如果该帖子有 3 条评论,ORM 将向数据库查询 3 次以查找每个用户的电子邮件。但如果我使用{{comment.user_id}}它,它只会查询一次,因为它会预加载 user_id,因为它在评论表中可用。

有什么方法可以只对数据库进行一次查询来获取所有评论的所有名称?

django django-templates django-models django-orm django-views

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