首页 > 解决方案 > 字段不识别 django

问题描述

我在我的项目中使用表单集时遇到了问题,我一直在努力解决这个问题。这样做时,出现了几个不同的错误。一般来说,我想要做的是创建实体 A 的对象(锻炼)并重定向到模板/url,让我用实体 B 的对象“填充”它,我将使用模型表单集动态地制作它. 问题似乎围绕表单展开,更具体地说:如果我一一编写字段,如:

CycleFormSet = modelformset_factory(
    Cycle, fields=('reps', 'place_in_workout', 'exercise', 'number_of_times', 'break_inbetween'), extra=1
)

然后,当我尝试运行服务器时,出现错误:Unknown field(s) (place_in_workout, break_inbetween, reps, number_of_times)。如果我对某些字段使用 exclude 或执行 fields = ' all ' ,那么此时我不会收到错误消息。但是,当我尝试发布锻炼对象的数据时,出现错误:['ManagementForm data is missing or has been tampered with']。我的代码:

模型.py

class Exercise(models.Model):
    name = models.CharField(max_length=150)
    description = models.TextField(max_length=500)

    def __str__(self):
        return self.name


class Workout(models.Model):
    name = models.CharField(max_length=150, null=True)
    created_by_user = models.ForeignKey(User, null=True, on_delete=models.RESTRICT)
    description = models.TextField(max_length=1000, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class Cycle(models.Model):
    place_in_workout = models.IntegerField
    exercise = models.ManyToManyField(Exercise)
    number_of_times = models.IntegerField
    reps = models.IntegerField
    break_inbetween = models.IntegerField
    workout = models.ManyToManyField(Workout)


class WorkoutCompleted(models.Model):
    datetime = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, on_delete=models.RESTRICT)

表格.py

class CreateUserForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']


class WorkoutForm(forms.ModelForm):
    class Meta:
        model = Workout
        fields = ['name', 'description']


class ExerciseForm(forms.ModelForm):
    class Meta:
        model = Exercise
        fields = ['name', 'description']


CycleFormSet = modelformset_factory(
    Cycle, fields='__all__', extra=1
)

网址.py

urlpatterns = [
    path('register/', views.register_page, name='register'),
    path('login/', views.login_page, name='login'),
    path('logout', views.logout_page, name='logout'),

    path('', views.index, name='index'),
    path('browse/', views.browse, name='browse'),
    path('workouts/<str:user_id>/', views.workouts, name='workouts'),


    path('add_exercise/', views.add_exercise, name='add_exercise'),
    path('create_workout/<str:user_id>/', views.fill_workout, name='fill_workout')
]

视图.py

@login_required(login_url='login')
def workouts(request, user_id):
    context = {}
    if request.method == 'POST':
        form = WorkoutForm(request.POST)
        if form.is_valid():
            workout = form.save(commit=False)
            workout.created_by_user = request.user
            workout.save()
            workout_id = workout.id
            context = {'workout_id': workout_id}

        return render(request, 'Trainmate/fill_workout.html', context)

    else:
        form = WorkoutForm()
        workout_programs = Workout.objects.all()
        user_workouts = workout_programs.filter(created_by_user=user_id)
        context = {'user_workouts': user_workouts, 'form': form}
        return render(request, 'Trainmate/workouts.html', context)


@login_required(login_url='login')
def fill_workout(request, user_id):
    if request.method == 'POST':
        # workouts = Workout.objects.filter(created_by_user__exact=request.user).order_by('-created_at')
        # current_workout = workouts[0]
        # pk_workout = current_workout.id
        pk_workout = 1
        formset = CycleFormSet(request.POST)
        if formset.is_valid():
            for form in formset:
                cycle = form.save(commit=False)
                cycle.workout = Workout.objects.get(pk=pk_workout)
                cycle.save()
        context = {}
        return render(request, 'Trainmate/home.html', context)
    else:
        formset = CycleFormSet(queryset=Cycle.objects.none())
        context = {'formset': formset}
    return render(request, 'Trainmate/fill_workout_with_sets', context)

(有更多的观点,我没有包括一些关于登录/注销的观点,如果被问到,我会的,我不想让帖子变得比现在更大)。另外,我已经用评论部分运行了视图,我相信我在查询集上犯了一些错误,因此我给了 pk_workout=1 以便查询集中的错误不相关。数据库中始终至少有一个锻炼对象。

锻炼.html

{% extends 'Trainmate/main.html' %}

{% block content %}
<h1>My Workouts</h1>

<div>
    {% for workout in user_workouts %}
        <tr>
            <td>{{ workout.name }}</td>
            <td><a class="btn btn-sm btn-info" href="">Update</a></td>
            <td><a class="btn btn-sm btn-info" href="">Delete</a></td><br>
        </tr>
    {% endfor %}
</div>

<h1>Create new Workout</h1>
<form method="POST" action="{% url 'fill_workout' request.user.id %}">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Create Workout">
</form>
{% endblock %}

fill_workout.html

{% extends 'Trainmate/main.html' %}

{% block content %}

<h1>Fill workout with sets</h1>

    <form id="form_container" method="POST" action="">
        {% csrf_token %}
        {{ formset.management_form }}
        {% for form in formset %}
        <div class="set_form">
            {{ form.as_p }}
        </div>
        {% endfor %}
        <button id="add-form" type="button">Add another set</button>
        <button type="submit"> Create Cycle</button>
    </form>

let set_form = document.querySelectorAll(".set_form")
let container = document.querySelector("#form_container")
let add_button = document.querySelector("#add_form")
let total_forms = document.querySelector("#id_form-TOTAL-FORMS")

let form_num = set_form.length -1

add_button.addEventListener('click',add_form)

function add_form(e){
    e.preventDefault()

    let new_form = set_form[0].cloneNode(true)
    let form_regex = RegExp(`form-(\\d){1}-`,'g')

    form_num ++
    new_form.innerHTML = new_form.innerHTML.replace(form_regex, `form-${form_num}-`)
    container.insertBefore(new_form, add_button)

    total_forms.setAttribute('value', `${form_num + 1}`)
}



{% endblock %}

我尝试运行服务器并使用锻炼对象的名称和描述完成表单,而没有上面模板的 javascript 部分,我仍然得到同样的错误。

很抱歉,很长的帖子和 ,我在发布之前一直在努力缩小我的问题范围,但似乎我一无所获。

标签: djangoviewformset

解决方案


在模型中定义字段时需要初始化字段,模型中的模型()字段缺少括号Cycle

class Cycle(models.Model):
    place_in_workout = models.IntegerField()
    exercise = models.ManyToManyField(Exercise)
    number_of_times = models.IntegerField()
    reps = models.IntegerField()
    break_inbetween = models.IntegerField()
    workout = models.ManyToManyField(Workout)

推荐阅读