【问题标题】:How to change a field in parent class while creating chiled class fields in forms.py and views.py?在forms.py和views.py中创建子类字段时如何更改父类中的字段?
【发布时间】:2019-10-10 20:59:53
【问题描述】:

我正在创建 ModelForm 我尝试更改父类,同时将子类字段保存到数据库中,在我创建的 views.py 中,但它没有保存到数据库中。 这是我的model.py

class Table(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    book = models.BooleanField(default=False)

class People(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
    taple = models.OneToOneField(Table, on_delete=models.CASCADE, null=True, blank=True)

@receiver(post_save, sender=User)
def update_people_profile(sender, instance, created, **kwargs):
    try:
        instance.people.save()
    except ObjectDoesNotExist:
        People.objects.create(user=instance)

类 People 是子类,Table 是父类,所以我使用 People 类来制作表格。这是我的forms.py

class Booking(forms.ModelForm):

    class Meta:
        model = People
        fields = [
            'taple',
        ]

所以我想True Table 类中的book 字段 并在保存预订表单时将其保存到数据库中。这是我的意见。py

def booking(request):
    if request.method == 'POST':
        try:
            people_instance = People.objects.get(user=request.user)
        except Table.DoesNotExist:
            people_instance = People(user=request.user)
        form = Booking(request.POST, instance=people_instance)
        if form.is_valid():
            user = form.save(commit=False)
            user.taple.booking = True
            user.refresh_from_db()
            user.user = request.user
            user.taple = form.cleaned_data.get('taple')
            user.save()
            print(user.taple.booking, user.taple.id)
            return redirect('booked')
    else:
        form = Booking()
    return render(request, 'main/booking.html', {'form': form})

有什么想法吗?

【问题讨论】:

    标签: python django django-models django-forms django-views


    【解决方案1】:

    我从 sn-ps 中了解到,您希望能够记录是否预订了一张桌子(在您的 Table 模型中预订 Boolean Field,如果预订了,那么由谁预订,这是您的 People 模型的对象。

    如果我的理解是正确的,那么我认为你真的不需要连接表(人物模型)。相反,我会改变你的模型如下:

    class Table(models.Model):
        restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
        booked_by = models.OneToOneField(User, null=True, on_delete=models.SET_NULL, related_name='table_booked')
    
        @property
        def is_booked(self):
            # This returns True if booked_by is set, False otherwise
            return self.booked_by_id is not None
    

    这样您就不需要 People 模型。属性装饰器将允许您使用 is_booked 作为计算字段。 另外,请注意将在表单中使用的相关名称:

    class BookingForm(forms.ModelForm):
        table_booked = forms.ModelChoiceField(queryset=Table.objects.filter(booked_by__isnull=True))
        class Meta:
            model = User
            fields = ['table_booked',]
    

    在表单中,您将看到我们为 table_booked 定义了一个自定义查询集。目的是仅过滤免费表。

    那么您也可以简化您的视图,如下所示:

    更新: 由于 table_booked 是反向外键,我们实际上需要保存包含关系的表对象。这是修改后的视图:

    @login_required
    def booking(request):
        form = BookingForm(request.POST or None, instance=request.user)
        if form.is_valid():
            user = form.save(commit=False)
            tbl = form.cleaned_data['table_booked']
            tbl.booked_by = request.user
            tbl.save()
            user.save()
            print(request.user.table_booked.id, request.user.table_booked.is_booked)
            return redirect('/')
        return render(request, 'booking/booking.html', {'form': form})
    

    注意:我还没有测试过代码,所以可能会有一些拼写错误,但这应该可以帮助您入门。

    【讨论】:

    • 我同意你的看法
    • 是的,你明白我的问题,谢谢极客,我会测试代码。
    • 兄弟你没有声明user变量
    • 我在尝试 makemigrations 时收到此错误 django.core.exceptions.FieldError: Cannot resolve keyword 'is_booked' into field. Choices are: booked_by, booked_by_id, restaurant, restaurant_id
    • 我的错,不能将属性用于数据库操作,例如过滤。 BookingForm 修改如下:table_booked = ModelChoiceField(queryset=Table.objects.filter(booked_by__isnull=True))
    猜你喜欢
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 2019-07-08
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多