Django:如何制作一个独特的空白模型.CharField?

发布于 2024-10-15 05:01:24 字数 1621 浏览 8 评论 0原文

想象一下,我有一个模型来描述办公室拥有的打印机。他们可能已准备好工作,也可能尚未准备好工作(可能在存储区,或者已购买但尚未在办公室......)。该模型必须有一个表示打印机物理位置的字段(“秘书办公室”、“接待处”……)。不能有两个重复的位置,如果它不起作用,它就不应该有一个位置。

我想要一个列表,其中显示所有打印机,并且每台打印机都有它所在的位置(如果有)。像这样的事情:

ID | Location
1  | "Secretary's office"
2  |
3  | "Reception"
4  | 

这样我就可以知道有两台打印机正在工作(1 和 3),而其他打印机则处于离线状态(2 和 4)。

该模型的第一种方法应该是这样的:

class Printer(models.Model):
      brand = models.CharField( ...
      ...
      location = models.CharField( max_length=100, unique=True, blank=True )

但这不能正常工作。您只能在一个空白位置存储一个寄存器。它在数据库中存储为空字符串,并且不允许插入多次(数据库表示该字段还有另一个空字符串)。如果您添加“null=True”参数,它的行为方式相同。这是因为,默认值是空字符串,而不是在相应列中插入 NULL 值。

在网上搜索我发现 http://www.maniacmartin .com/2010/12/21/unique-nullable-charfields-django/,尝试以不同的方式解决问题。他说最干净的可能是最后一个,其中他对 CharField 类进行子类化并重写一些方法以在数据库中存储不同的值。这是代码:

from django.db import models
class NullableCharField(models.CharField):
     description = "CharField that obeys null=True"
     def to_python(self, value):
         if isinstance(value, models.CharField):
             return value
         return value or ""

     def get_db_prep_value(self, value):
         return value or None

这工作正常。您可以存储多个没有位置的寄存器,因为它不是插入空字符串,而是存储 NULL。这样做的问题是它用 None 而不是空字符串显示空白位置。

ID | Location
1  | "Secretary's office"
2  | None
3  | "Reception"
4  | None

我认为有一个(或多个)方法必须指定如何在模型和数据库类管理器之间以两种方式(数据库到模型和模型到数据库)转换数据。

这是拥有独特的空白 CharField 的最佳方式吗?

谢谢,

Imagine that I have a model that describes the printers that an office has. They could be ready to work or not (maybe in the storage area or it has been bought but not still in th office ...). The model must have a field that represents the phisicaly location of the printer ("Secretary's office", "Reception", ... ). There cannot be two repeated locations and if it is not working it should not have a location.

I want to have a list in which all printers appear and for each one to have the locations where it is (if it has). Something like this:

ID | Location
1  | "Secretary's office"
2  |
3  | "Reception"
4  | 

With this I can know that there are two printers that are working (1 and 3), and others off line (2 and 4).

The first approach for the model, should be something like this:

class Printer(models.Model):
      brand = models.CharField( ...
      ...
      location = models.CharField( max_length=100, unique=True, blank=True )

But this doesn't work properly. You can only store one register with one blank location. It is stored as an empty string in the database and it doesn't allow you to insert more than one time (the database says that there is another empty string for that field). If you add to this the "null=True" parameter, it behaves in the same way. This is beacuse, instead of inserting NULL value in the corresponding column, the default value is an empty string.

Searching in the web I have found http://www.maniacmartin.com/2010/12/21/unique-nullable-charfields-django/, that trys to resolve the problem in differnt ways. He says that probably the cleanest is the last one, in which he subclass the CharField class and override some methods to store different values in the database. Here is the code:

from django.db import models
class NullableCharField(models.CharField):
     description = "CharField that obeys null=True"
     def to_python(self, value):
         if isinstance(value, models.CharField):
             return value
         return value or ""

     def get_db_prep_value(self, value):
         return value or None

This works fine. You can store multiple registers with no location, because instead of inserting an empty string, it stores a NULL. The problem of this is that it shows the blank locations with Nones instead of empty string.

ID | Location
1  | "Secretary's office"
2  | None
3  | "Reception"
4  | None

I supposed that there is a method (or multiple) in which must be specify how the data must be converted, between the model and the database class manager in the two ways (database to model and model to database).

Is this the best way to have an unique, blank CharField?

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝颜夕 2024-10-22 05:01:24

您可以使用模型方法以自定义方式输出值。

像这样(在您的模型类中):

def location_output(self):
    "Returns location and replaces None values with an empty string"
    if self.location:
        return self.location
    else:
        return ""

然后您可以在这样的视图中使用它。

>>> Printer.objects.create(location="Location 1")
<Printer: Printer object>
>>> Printer.objects.create(location=None)
<Printer: Printer object>
>>> Printer.objects.get(id=1).location_output()
u'Location 1'
>>> Printer.objects.get(id=2).location_output()
''

在你的模板中,像这样。

{{ printer.location_output }}

You can use a model method to output the values in a custom way.

Like this (in your model class):

def location_output(self):
    "Returns location and replaces None values with an empty string"
    if self.location:
        return self.location
    else:
        return ""

Then you can use it in views like this.

>>> Printer.objects.create(location="Location 1")
<Printer: Printer object>
>>> Printer.objects.create(location=None)
<Printer: Printer object>
>>> Printer.objects.get(id=1).location_output()
u'Location 1'
>>> Printer.objects.get(id=2).location_output()
''

And in your templates, like this.

{{ printer.location_output }}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文