【问题标题】:Giving positions name in django automatically在 django 中自动给出职位名称
【发布时间】:2017-05-01 18:15:44
【问题描述】:

我正在使用 Django 构建一个巴士预订网站。我的桌子“座位”中有一个属性位置。它通过外键链接到总线(表)。每当创建总线时,都会创建等于总线容量的座位实例(容量由用户在总线表中定义)。我想将位置命名为 1_1、1_2、1_4、1_5、2_1、2_2、2_4、2_5 等。其中下划线之前的第一个数字代表行,下划线之后的数字代表一列。我没有使用 3,因为它是过道。

这是我的models.py

class Seat(models.Model):
    class Meta:
        verbose_name_plural = "Seat"
    id = models.AutoField(primary_key=True,)
    position = models.CharField(max_length=4)
    bus = models.ForeignKey(Bus)
    status = models.CharField(max_length=20, choices=(('available', 'available'), ('reserved', 'reserved'), ('unavailable', 'unavailable'),), default='Available')

    def __str__(self):
        return '{0}-{1}-{2}'.format((self.bus),(self.id),(self.status))

@receiver(post_save, sender=Bus)
def create_seats(sender, instance, created, **kwargs):
    if created:
        for seat in range (0, int(instance.capacity)):
            instance.seat_set.create( )

位置的命名是这样完成的

你可以看到它在中间是空的,所以第三列没有被使用。我的问题是如何根据图表自动命名位置(就像我在创建公共汽车对象时创建座位一样),而无需进入单独的座位对象并命名位置。我希望你能得到我的问题。如果您需要更多信息,请告诉我。

【问题讨论】:

    标签: python django


    【解决方案1】:

    这个答案假设公交车可以有不同的座位布局,这意味着您需要为每种公交车类型定义座位模式。

    最基本的方法是将它们定义为常量、二维列表/数组,输入 1 表示有座位,输入 0 表示没有座位:

    #seating_patterns.py
    
    BUS_1 = [
        [1, 1, 0, 1, 1],
        [1, 1, 0, 1, 1],
        [1, 1, 0, 1, 1],
        [1, 1, 0, 1, 1],
        [1, 1, 0, 0, 0],
        [1, 1, 0, 1, 1],
        [1, 1, 0, 1, 1],
        [1, 1, 0, 1, 1],
        [1, 1, 1, 1, 1],
    ]
    
    BUS_2 = [etc]
    
    SEATING_ARRAYS = {'BUS_1': BUS_1, 'BUS_2': BUS_2}
    

    为了使其更易于维护,您可以创建一个 SeatingPattern 模型,例如,如果您可以选择使用 ArrayField。

    否则将座位阵列导入您的模型文件:

    # models.py
    from .seating_patterns import SEATING_ARRAYS
    

    并为您的巴士模型添加一个座位模式字段,并为巴士添加一个选择元组:

    class Bus(models.Model):
    …
    SEATING_PATTERNS = (
        ('BUS_1', 'BUS_1'),
        ('BUS_2', 'BUS_2'),
    )
    …
    seating_pattern = models.CharField(choices=SEATING_PATTERNS, max_length=50)
    

    并在您的 post_save 信号中创建像这样的正确格式输出(1_1、1_2 等):

    if created:
        seating_pattern = SEATING_ARRAYS[instance.seating_pattern]
        for row,seats in enumerate(seating_pattern):
            for pos,seat in enumerate(seats):
                if seat:
                    Seat.objects.create(
                        bus=instance,
                        position="{}_{}".format(str(row+1), str(pos+1))
                    )
    

    【讨论】:

    • 它会产生这个错误“选择一个有效的选择。 [[1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [ 1, 1, 0, 0, 0], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 1, 1, 1]] 不是可用的选择之一。'
    • 好的,我已经稍微编辑了代码 - 现在应该可以工作了。查看 SEATING_PATTERNS 的变化、新的 SEATING_ARRAYS 和 post_save 信号的变化。我无法让 bulk_create 工作,所以现在它在循环中创建对象 - 如果这是性能问题,您可能想尝试更改它。此外,保存座位数组的更好方法是在 ArrayField 中,我认为只有在使用 Postgres 数据库时才可用。
    【解决方案2】:

    假设总线布局始终相同:

    @receiver(post_save, sender=Bus)
    def create_seats(sender, instance, created, **kwargs):
        if created:
            for place_num in range(1, int(instance.capacity)+1):
                row = (place_num // 5) + 1
                col = (place_num % 5) + 1
                if col != 3 and row*col not in [24, 25]:
                    instance.seat_set.create(position='%i_%i' % (row, col))
    

    【讨论】:

    • 如果布局发生变化?
    • 如果布局发生变化,您可以使用@birophilo 建议的方法
    • 它会产生这个错误“选择一个有效的选择。 [[1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [ 1, 1, 0, 0, 0], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 0, 1, 1], [1, 1, 1, 1, 1]] 不是可用的选择之一。'
    猜你喜欢
    • 2021-02-26
    • 1970-01-01
    • 2018-11-18
    • 2011-12-30
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    相关资源
    最近更新 更多