这是我第一次在这里问问题:)我是一个Django的初学者,我已经被我的edit_booking方法卡住了好几天,我甚至不知道我做错了什么. 我在做一个预订系统,我得到了"TypeError at /edit-booking/6 __init__() got an unexpected keyword argument 'id'"分.我一直在try 很多事情,使编辑准确的预订可能,但他们只会导致更多的错误.

意见:

class EditBooking(DetailView):

    def __init__(self):    
        template_name = 'edit-profile.html'        
        initial = {}

    @login_required
    def edit_booking(request, id):
        booking = get_object_or_404(Booking, id=id)
        if request.method == 'POST':
            form = BookingForm(request.POST, instance=booking)
            customer_data = UserProfile.objects.all()
            if form.is_valid():
                instance = form.save(commit=False)
                instance.customer_data = customer_data
                instance.save()
                messages.success(request, 'Thank you! Your booking has been updated!')
            else:
                return messages.error(request, form.errors)
        else:
            form = BookingForm(initial={
                'booking_date': booking.booking_date,
                'booking_time': booking.booking_time,
                'table_size': booking.table_size,
                'additional_info': booking.additional_info,
            })
        return render(request, template_name, {'form': form})

以下模板可用:

触发编辑页面的Profile.html按钮:

<a href="{% url 'editbooking' id=booking.id %}" aria-label="edit booking">
    <button type="button" class="btn btn-secondary btn-brown px-5">Edit</button>
</a>

EDIT_Booking.html:

<form method="POST" action="{% url 'editbooking' id=booking.id %}" 
class="col-6">                                  
    {% csrf_token %}
    {% crispy form %}
</form>

URL:

path('edit-booking/<int:id>', views.EditBooking, name='editbooking'),

型号:

class Booking(models.Model):

    booking_customer = models.ForeignKey(UserProfile, on_delete=models.CASCADE, null=True)
    booking_date = models.DateField(default=datetime.date.today)
    booking_time = models.CharField(choices=TIME_SLOTS, default='8:00 - 8:30', max_length=50)
    table_size = models.CharField(choices=TABLE_SIZE, default='1', max_length=50)
    additional_info = models.TextField(max_length=400, null=True, blank=True)
    booked_on = models.DateTimeField(auto_now_add=True)
    is_confirmed = models.CharField(choices=CONFIRMATION, default='Awaiting confirmation', max_length=50)
    slug = AutoSlugField(max_length=70, unique=True, null=True)


    class Meta:
        ordering = ["booked_on"]
        

    def __str__(self):

        return f'Booking for {self.booking_date} at {self.booking_time} was booked on {self.booked_on} and currently has a status: {self.is_confirmed}'

表格:

class BookingForm(ModelForm):
    """ 
    Provides necessary fields to the booking form for customers
    """

    def __init__(self, *args, **kwargs):

        super().__init__(*args, **kwargs)

        # Crispy form helpers
        self.helper = FormHelper()
        self.helper.form_method = 'post'        
        self.helper.add_input(Submit('submit', 'Submit', css_class='btn btn-secondary btn-brown mb-4 mx-auto px-5'))        

    # Provides a date widget to the form 
    booking_date = forms.DateField(widget=forms.DateInput(attrs={'class':'form-control', 'type':'date', 'value': datetime.date.today}), required=False)
    booking_time = forms.ChoiceField(choices=TIME_SLOTS, required=False)
    table_size = forms.ChoiceField(choices=TABLE_SIZE, required=False)
    additional_info = forms.CharField(max_length=400, widget=SummernoteWidget(), required=False)
    booked_on = forms.DateTimeField(initial=datetime.datetime.now, widget=forms.HiddenInput(), required = False)
    slug = AutoSlugField(max_length=70, unique=True, populate_from=lambda instance: instance.title,
                         unique_with=['booked_on', 'booking_date'],
                         slugify=lambda value: value.replace(' ','-')) 


    # Provides a model to pull the fields from
    class Meta:
        model = Booking
        fields = ['booking_date', 'booking_time', 'table_size', 'additional_info']
        read_only = ['booked_on', 'slug']


    # Prevents booking dates in the past
    def save_booking(self, *args, **kwargs):

        data = self.cleaned_data
        if data.get('booking_date') < datetime.date.today():        
            raise ValidationError("The date cannot be in the past!")
        else:
            super(Booking, self).save(*args, **kwargs)

我试图使用slug、pk和id来获得准确的预订,我更改了URL和模板以显示id,使用Booking.objects.get()并在最后将其与Get_Object_or_404交换,摆脱init等……我在这里一直在寻找类似的问题,但我try 的解决方案都没有真正对我起作用:

推荐答案

这里有几个问题.首先,您使用.as_view()注册了一个基于类的视图,它实质上将类包装到一个处理请求的函数中,因此:

path('edit-booking/<int:id>', views.EditBooking.as_view(), name='editbooking'),

您现在可能会收到关于template_name和没有指定模型的错误,这是有道理的:您没有定义它,而是试图在构造函数中定义它.你的视野看起来也很像UpdateView [Django-doc],而不是DetailView.您可以将UpdateView视为DetailView,但带有允许编辑的表单.这还将用GET请求中已有的实例填充表单,这可能会使它更方便.

我们可以用LoginRequiredMixin [Django-doc]美元 和SuccessMessageMixin [Django-doc],用于判断用户是否已登录,并在项目成功时已对消息进行编码:

没有多大意义的是.customer_data = customer_data:您不会将其存储在模型对象中.您可以将.booking_customer设置为登录用户的UserProfile,但这取决于UserProfile型号,因此您可能必须修改form_valid()方法重载.

最后,一个成功的POST请求通常会导致重定向到某个路径,您可以通过success_url:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic import UpdateView


class EditBooking(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
    model = Booking
    form_class = BookingForm
    template_name = 'edit-profile.html'
    success_message = 'Thank you! Your booking has been updated!'
    success_url = '/path/to/some/view'

    # no __init__

    def form_valid(self, form):
        form.instance.booking_customer = UserProfile.objects.get(
            user=self.request.user
        )
        return super().form_valid(form)

Django相关问答推荐

批量删除多对多条目?

int_list_validator在 Django 表单中不起作用

防止 Django 从表单集中保存特定表单

在 PyCharm 中运行 Django 测试

更好的 ArrayField 管理小部件?

从python中的URL获取查询字符串的最佳方法?

断开模型的信号并在 django 中重新连接

django - pisa:将图像添加到 PDF 输出

手动触发 Django 邮件错误报告

如何使用 django 发送 POST 请求?

在 virtualenv Ubuntu 12.10 中使用 pip 安装 lxml 错误:command 'gcc' failed with exit status 4

OrderingFilter 没有属性filter_queryset

__init__() 得到了一个意外的关键字参数user

如何从 Django 的 TabularInline 管理视图中省略对象名称?

如何将 django csrf 令牌直接嵌入 HTML?

Django:以 10 为底的 int() 的无效文字

访问 django 管理模板中的对象

如何将本地文件分配给 Django 中的 FileField?

Heroku & Django:OSError: No such file or directory:'/app/{myappname}/static'

Django:根据自定义函数过滤查询