一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 關于Django外鍵賦值問題詳解

關于Django外鍵賦值問題詳解

2020-12-01 00:48Youmai Python

這段時間用django 做程序用到了一對多的關系的操作,下面分享一些心得體會,這篇文章主要給大家介紹了關于Django外鍵賦值問題的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。

本文主要給大家介紹關于Django外鍵賦值的相關內容,分享出來供大家參考學習,在開始之前,我們先來看一段代碼:

?
1
2
3
4
5
6
7
8
9
class Article(models.Model):
 title = models.CharField(max_length=1024, default='')
 ...
 def __str__(self):
  return 'Article pk:%d %s' % (self.pk, self.title[:30])
 
class ArticleContent(models.Model):
 article = cached_fields.OneToOneField(Article)
 ...

寫代碼的的時候,發現了一個很奇怪的現象,當我給一個instance的外鍵(以_id結尾)賦值(數字)的時候 ,這個外鍵對應的instance的值并不會改變。

?
1
2
3
4
5
6
7
8
9
In [44]: ac = ArticleContent.objects.get(article_id=14269)
In [45]: ac.article_id
Out[45]: 14269
In [46]: ac.article_id = 14266
In [47]: ac.save()
In [48]: ac.article
Out[48]: <Article: Article pk:14266 EC: Russia, Ukraine to Meet in>
In [49]: ac.article.pk
Out[49]: 14266

如上面的代碼所示,為了找到答案,我翻了一下Django的源碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
django/db/models/fields/related_descriptors.py
  def __get__(self, instance, cls=None):
   """
   Get the related instance through the forward relation.
 
   With the example above, when getting ``child.parent``:
 
   - ``self`` is the descriptor managing the ``parent`` attribute
   - ``instance`` is the ``child`` instance
   - ``cls`` is the ``Child`` class (we don't need it)
   """
   if instance is None:
    return self
 
   # The related instance is loaded from the database and then cached in
   # the attribute defined in self.cache_name. It can also be pre-cached
   # by the reverse accessor (ReverseOneToOneDescriptor).
   try:
    rel_obj = getattr(instance, self.cache_name)
   except AttributeError:
    val = self.field.get_local_related_value(instance)
    if None in val:
     rel_obj = None
    else:
     qs = self.get_queryset(instance=instance)
     qs = qs.filter(self.field.get_reverse_related_filter(instance))
     # Assuming the database enforces foreign keys, this won't fail.
     rel_obj = qs.get()
     # If this is a one-to-one relation, set the reverse accessor
     # cache on the related object to the current instance to avoid
     # an extra SQL query if it's accessed later on.
     if not self.field.remote_field.multiple:
      setattr(rel_obj, self.field.remote_field.get_cache_name(), instance)
    setattr(instance, self.cache_name, rel_obj)
 
   if rel_obj is None and not self.field.null:
    raise self.RelatedObjectDoesNotExist(
     "%s has no %s." % (self.field.model.__name__, self.field.name)
    )
   else:
    return rel_obj

注釋得非常到位,當我們請求ac.article的時候,會先去檢查對應的cache(在這里是_article_cache,感興趣可以去看cache_name的生成規則,就是外鍵名前面加下劃線,后面加cache)存不存在,如果不存在那么就進行數據庫請求,請求完之后會保存到cache中。

我們再看看__set__ ,代碼太長就不貼了(就在__get__方法下面)。除了給外鍵字段(article)賦值外,還會將pk字段(article_id,是lh_field.attname的值)設置為None,這樣下次請求的時候就能拿到正確的值。

以上都是ForeignKey的Magic,而當我們給article_id賦值的時候,只是在給一個普通的attribute賦值而已,沒有任何magic,不會清理對應外鍵的cache,這時候拿到的instance仍然是cache中原來的那個instance。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://michaelyou.github.io/2016/12/19/Django外鍵賦值/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 激情涩涩 | 国产成人影院在线观看 | 九九365资源稳定资源站 | 四虎国产精品免费久久麻豆 | 好紧好爽的午夜寂寞视频 | 日韩精品亚洲一级在线观看 | 欧美性另类69xxxx | 国产高清在线精品一区二区 | 91日本 | 亚洲欧美另类第一页 | 丰满肥臀风间由美357在线 | 国产精品毛片高清在线完整版 | 九九九精品视频 | 国产99青草全福视在线 | 久青草国产97香蕉在线视频 | 互换娇妻爽文100系列小说 | 女人麻豆国产香蕉久久精品 | 美女脱了内裤张开腿亲吻男生 | 成人不卡在线 | 99精品在线视频观看 | 精品一区二区三区自拍图片区 | 日本高清不卡一区久久精品 | 2021国产麻豆剧传媒剧情动漫 | ai换脸明星专区在线观看 | 青青草在线播放 | 欧美日韩国产成人综合在线影院 | 国产精品99久久 | 亚洲日日做天天做日日谢 | 国色天香社区在线视频免费观看 | 日本hd18 | 臀精插宫NP文| 好湿好紧太硬了我太爽了网站 | 色综合天天综合网看在线影院 | 范冰冰好紧好滑好湿 | 操美女| 毛片免| 四虎影视在线看 | 国产成人亚洲综合a∨婷婷 国产成人亚洲精品乱码在线观看 | 精品一区二区视频 | 我的男友是消防员在线观看 | 婷婷日日夜夜 |