【问题标题】:why is django altering my data after I import it?为什么 django 在我导入数据后会更改我的数据?
【发布时间】:2021-02-04 00:21:07
【问题描述】:

更新后包含来自种子文件的样本

我使用端点在我的 Django API 中清除和重新植入我的数据。数据来自存储在我的项目中的两个对象数组,然后导入到我的views.py。一个数组是配置文件,另一个是帖子,其中包括用作引用配置文件的外键的整数。这在我重新启动服务器后第一次运行这些功能时效果很好。但是,当我再次运行该函数时,django 会以某种方式更改我导入的数据以将整数交换为它引用的整个引用的数据库对象。显然,这会破坏我的代码。

在views.py中:

from .fixtures.seed import all_profiles, all_posts

def seed(request):
    print('all posts zero: ', all_posts[0]['profile']) #logging the issue in question
    Profile.objects.all().delete()
    reset(Profile)
    for profile in all_profiles:
        add_profile(profile)
    Post.objects.all().delete()
    reset(Post)
    for post in all_posts:
        add_post(post)
    return HttpResponse('database cleared and seeded')

def add_profile(new_profile):
    profile_instance = Profile.objects.create(**new_profile)
    profile_instance.save()

def add_post(new_post):
    found_profile = Profile.objects.get(id=new_post['profile'])
    new_post['profile'] = found_profile
    post_instance = Post.objects.create(**new_post)
    post_instance.save()

def reset(table):
    sequence_sql = connection.ops.sequence_reset_sql(no_style(), [table])
    with connection.cursor() as cursor:
        for sql in sequence_sql:
            cursor.execute(sql)

seed.py 中的代码示例:

all_profiles = [
  {
    "name": "Robert Fitzgerald Diggs",
    "profile_name": "RZA",
    "email": "abbotofthewu@wutang.com"
  },
...
]

all_posts = [
  {
    "title": "Bring da Ruckus",
    "body": "'Shaolin shadowboxing and the Wu-Tang sword style If what you say is true, The Shaolin and the Wu-Tang could be dangerous",
    "profile": 5
  },
...
]

首次运行种子功能时记录:

all posts zero:  5
[04/Feb/2021 00:01:37] "GET /utility/seed/ HTTP/1.1" 200 27

第二次运行时记录:

all posts zero:  Corey Woods
Internal Server Error: /utility/seed/
Traceback (most recent call last):
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 1774, in get_prep_value
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Profile'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/main_app/views.py", line 79, in seed
    add_post(post)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/main_app/views.py", line 91, in add_post
    found_profile = Profile.objects.get(id=new_post['profile'])
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 418, in get
    clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 942, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 962, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, *args, **kwargs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/query.py", line 969, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1358, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1377, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1319, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1165, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/lookups.py", line 24, in __init__
    self.rhs = self.get_prep_lookup()
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/lookups.py", line 76, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "/Users/jedgodsey/Documents/Projects/fromtheslumsofJSON/.venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 1776, in get_prep_value
    raise e.__class__(
TypeError: Field 'id' expected a number but got <Profile: Corey Woods>.
[04/Feb/2021 00:01:43] "GET /utility/seed/ HTTP/1.1" 500 134068

这到底是怎么回事?这是我被警告过的 django “黑魔法”吗?我试图有条件地进行设置以使事情正常进行,但到目前为止还没有成功。我猜 django 将我导入的数据存储在内存中的某个地方,而不是每次运行时都重新导入,但我看不到任何我指示它更改数据的地方。任何帮助将不胜感激。

【问题讨论】:

  • 您能否更新您的问题以包含来自.fixtures.seedall_postsall_profiles 的代码?
  • @Foot 是的,谢谢...刚刚更新了几个 sn-ps。

标签: python sql django api


【解决方案1】:

这是你自己做的,不涉及任何黑魔法。

    # Get a profile by ID using the `profile` key's value
    found_profile = Profile.objects.get(id=new_post['profile'])
    # Assign back to the same key (so it's now that model)
    new_post['profile'] = found_profile

由于您不获取种子数据或任何内容的副本,因此这种突变将在请求之间持续存在。第一个请求有效,后续请求无效。

如果您需要改变字典,您可能希望在该函数中执行new_post = new_post.copy() 来执行浅拷贝。

【讨论】:

  • 老大!谢谢!那么发生这种情况是因为只要服务器启动并从中获取参数而不是再次获取参数,该函数就基本上保持状态?
  • 是的,因为它只是来自导入模块的变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 2020-05-14
  • 1970-01-01
  • 2022-12-06
  • 2010-11-16
  • 2010-12-18
相关资源
最近更新 更多