Django 一对一字段

1 投票
2 回答
1452 浏览
提问于 2025-04-17 03:33

现在我在做一个网址映射的工作。假设我有三个类:公司、用户和商店,我的目标是让它们的网址在同一个层级上。因为它们的网址在同一个层级,所以我需要创建一个叫做url_mapping的类,以确保没有重复的名字。让我给你一个更具体的问题。

Class Company(models.Model):
    company_name  = models.CharField(max_length=30)
    url_mapping   = models.OneToOneField(URL_mapping)

Class User(models.Model):
    user_name  = models.CharField(max_length=30)
    url_mapping   = models.OneToOneField(URL_mapping)

Class store(models.Model):
    store_name  = models.CharField(max_length=30)
    url_mapping   = models.OneToOneField(URL_mapping)

Class URL_mapping(models.Model):
    url         = models.CharField(max_length=30)

现在,当访客通过某个网址访问我的网站时,我会在URL_mapping类中匹配这个网址,然后进行反向查找,看看这个网址是属于公司、用户还是商店。

由于用户、商店和公司有不同的视图功能,是否可以通过反向查找快速跳转到相应的视图功能?还是说我应该在URL_mapping中添加另一个字段,说明这个网址的类型是什么?

举个例子:

http://www.example.com/levis       ->  will handle by brand_views
http://www.example.com/david       ->  will handle by user_views
http://www.example.com/mancy       ->  will handle by store_views

在数据库中,我们会有:

url_mapping
id:1, name:levis
id:2, name:david
id:3, name:mancy

user
id:1, name:david, url_mapping:2

brand
id:1, name:levis, url_mapping:1

store
id:1, name: mancy, url_mapping:3

其中url_mapping是一个一对一的字段。

现在不知道如何快速从url_mapping类中查找。

谢谢。

2 个回答

3

我理解你的问题是“我有一个网址,我想去对应的商店、公司或用户。”

你可以通过下面的方式来实现:

URL_mapping.objects.get(url).user
URL_mapping.objects.get(url).store
URL_mapping.objects.get(url).company

不过,这里有两个选项会出错,你可能不知道它们分别对应什么。

在我看来,针对你真正想要的,最好使用通用外键

这样,你就可以做到:

URL_mapping.objects.get(url)

这样就能得到对应的UserCompanyStore模型。

1
  1. 我会在每个模型(公司、用户、商店)中使用一个叫做 SlugField 的字段,作为它们的标识符。

  2. 理论上,你根本不需要任何 URL 映射表。在处理请求的视图中,提取 URL 的最后一部分,这部分是用来识别公司、用户或商店的 slug,然后在公司、用户和商店模型中查找这个 slug。找到对象后就停止。

  3. 为了提高速度,你可以像之前那样创建一个辅助模型,并使用 GenericForeignKey 关系,正如 Lakshman Prasad 建议的那样。在这个辅助模型中,我也会使用 SlugField 作为标识符。如果你使用这个方法,就不需要在主要模型中使用 slug 了。

  4. 我个人觉得这个设计不好。首先,我怀疑这些 URL 是否符合 RESTful 规范。其次,为了让这个方法有效,主要模型中的 slug 必须在这三个模型中是唯一的,这只能通过外部机制来保证,不能在这里使用 UNIQUE 约束。你的 URL_mapping 模型就是这样一个机制。它基本上是在模型外部存储这三个模型的 slug,如果你在 URL_mapping 中的 SlugField 上添加 UNIQUE 约束,就能确保这些 slug 在主要模型中是唯一的。

撰写回答