【问题标题】:Django Model Forms including Foreign Key Fields包含外键字段的 Django 模型表单
【发布时间】:2021-09-13 04:01:20
【问题描述】:

我正在尝试在 Django 中创建一个模型表单,其中包含来自运动员表的外键字段。

通常在引用外键字段时,我可以使用字段名称“运动员”,然后是字段名称。这似乎不起作用。

我尝试过使用 ModelChoiceField 的查询集,但我认为我没有正确设置。

提前感谢您的帮助。

这是主要模型(ASP 预订),包括外键运动员

class ASPBookings(models.Model):

asp_booking_ref = models.CharField(max_length=10, default=1)
program_type = models.CharField(max_length=120, default='asp')
booking_date = models.DateField()
booking_time = models.CharField(max_length=10, choices=booking_times)
duration = models.CharField(max_length=10, choices=durations, default='0.5')
street = models.CharField(max_length=120)
suburb = models.CharField(max_length=120)
region = models.CharField(max_length=120, choices=regions, default='Metro')
post_code = models.CharField(max_length=40)
organisation_type = models.CharField(max_length=120,choices=organisation_types, default='Government School')
audience_number = models.CharField(max_length=10)
presentation_form = models.CharField(max_length=120, choices=presentation_form_options, default='Face to Face')
contact_name = models.CharField(max_length=80)
email = models.EmailField()
phone_number = models.CharField(max_length=120)
comments = models.TextField()
status = models.CharField(max_length=80, choices=statuses, default='TBC')
email_sent = models.BooleanField(default=False)
athlete = models.ForeignKey(Athlete, default= '1', on_delete=models.CASCADE)

def __str__(self):
    return self.contact_name

# return URL after the POST has been submitted.
def get_absolute_url(self):
    return reverse('vistours:success')

运动员模特

class Athlete(models.Model):


athlete_ref = models.CharField(max_length=10, default=1)
athlete_name = models.CharField(max_length=80)
email = models.EmailField()
phone_number = models.CharField(max_length=120)
home = models.CharField(max_length=120)
education = models.CharField(max_length=120)
sport = models.CharField(max_length=120, choices=sports, default='1500m Runner')
notes = models.TextField(default='None')
gender = models.CharField(max_length=120, choices=genders, default='Not Specified')
para_athlete = models.BooleanField(blank=True)
working_with_children = models.BooleanField(blank=True)
expiry_date = models.DateField(blank=True, null=True)
available = models.BooleanField(blank=True)
available_from = models.DateField(blank=True, null=True)
bfbw = models.BooleanField(blank=True)
latest_bfbw_session = models.DateField(blank=True, null=True)
number_bfbw_sessions = models.CharField(blank=True, null=True, max_length=10)
asp = models.BooleanField(blank=True)
latest_asp_session = models.DateField(blank=True, null=True)
number_asp_sessions = models.CharField(blank=True, null=True, max_length=10)
tours = models.BooleanField(blank=True)
latest_tours_session = models.DateField(blank=True, null=True)
number_tours_sessions = models.CharField(blank=True, null=True, max_length=10)

def __str__(self):
    return self.athlete_name

# return URL after the POST has been submitted.
def get_absolute_url(self):
    return reverse('home')

**下面是我尝试创建的表单,我需要表单来显示以下字段。 asp_booking_ref、program_type、运动员 id、运动员姓名。)我也尝试将这些显示为小部件,但在尝试添加时仅显示 asp_booking_ref 和 program_type 字段。

class ASPAssignAthleteForm(forms.ModelForm):
athlete = forms.ModelChoiceField(queryset=Athlete.objects.all())


class Meta():
    model = ASPBookings
    fields = '__all__'
    widgets = {

            'asp_booking_ref': TextInput(attrs={'id':'booking_id', 'name': 'booking_id'}),
            'program_type': TextInput(attrs={'id': 'program_type', 'name': 'program_type'}),
            
    }



 <!-- Assign ASP Athlete Modal -->
<form method="post" action='assign_athlete/' id="asp_assign_athlete_form">
  {% csrf_token %}
  {{ form.non_field_errors }}

  {{ form.source.errors }}
  {{ form.source }}


  <div class="modal fade" id="asp_assign_athlete_modal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
      <div class="modal-content">
        <div class="modal-header card-header">
          <h5 class="modal-title" id="asp_assign_athlete_modal_header" > <i class="fa fa-address-card-o mx-1"></i> Assign athlete</h5>
          <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="card text-dark bg-light mb-3">
            <div class="card-body">
              <div class="btn-group d-grid gap-2" role="group" aria-label="Basic outlined example">
                {% for athlete in ath_data %}
                {% for booking in asp_bookings %}
               
                {% if forloop.first %}
                {% if athlete.available == 1 %}
                
                 <form>
                  {{asp_assign_athlete_form.asp_booking_ref}}
                  {{asp_assign_athlete_form.program_type}}
                  {{asp_assign_athlete_form.athlete_name}}
                  {{asp_assign_athlete_form.athlete.id}}
                  {{asp_assign_athlete_form.athlete_id}}
                    <input type="submit" name="submit" value="{{athlete.athlete_name}}" class="btn btn-outline-primary w-100">
                    <input class="booking_id " type="text" name="booking_id" value="{{booking.id}}">
                    <input class="" type="text" name="program_type" value="{{booking.program_type}}">
                    <input class="" type="text" name="athlete_id" value="{{booking.athlete_id}}">
                    <input class="" type="text" name="athlete_ref" value="{{athlete.id}}">



                  </form>
                
          
                <!-- <a href="{% url 'vistours:assign_athlete' id=booking.id program_type=booking.program_type athlete_id=booking.athlete_id ath_id=athlete.id %}" class="data-vis-booking btn btn-outline-primary" data-vis-booking="{{booking.id}}">{{athlete.athlete_name}}</a> -->

          
                {% endif %}
                {% endif %}
                {% endfor %}
                {% endfor %}
              

            

              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</form>
<!-- END Assign ASP Athlete Modal -->

查看代码(分配运动员 - 流程)

def assign_athlete(request, id, program_type, athlete_id, ath_id):

    if request.method == 'POST':
        booking_id = request.POST.get('booking_id')
        asp_data = ASPBookings.objets.get(id=booking_id)
        asp_data.athlete_id = request.POST.get('athlete_ref')
        print(booking_id)
        print(athlete_ref)
        asp_data.save()

    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

查看页面代码

class admin_booking(View):
def get(self, request):

    # check whether the user is logged in.
    context = initialize_context(request)
    token = get_token(request)
    session = request.session
    if session.get('user') == None:
        return redirect('vistours:signin')

    # get the model data.
    asp_data = ASPBookings.objects.all()
    bfbw_data = BFBWBookings.objects.all()
    tour_data = SchoolTourBookings.objects.all()
    ath_data = Athlete.objects.all()

    # add the model data to a context dictionary
    context = {
            'asp_bookings': asp_data,
            'bfbw_bookings': bfbw_data,
            'tour_bookings': tour_data,
            'ath_data': ath_data,
            'ath_form': AthleteForm(),
            'asp_form': ASPBookingsForm(),
            'edit_asp_form': EditASPBookingsForm(),
            'bfbw_form': BFBWBookingsForm(),
            'edit_bfbw_form': EditBFBWBookingsForm(),
            'tours_form': SchoolTourBookingsForm(),
            'edit_tours_form': EditSchoolTourBookingsForm(),
            'asp_assign_athlete_form': ASPAssignAthleteForm(),
           
        }

    # Check for completed bookings
    completed_bookings(request)


    # Serialise the data to JSON output file.
    with open("vistours/static/vistours/json/asp.json", "w") as out:
        json_serializer = serializers.get_serializer('json')()
        json_serializer.serialize(asp_data, stream=out, indent=4)

    with open("vistours/static/vistours/json/bfbw.json", "w") as out:
        json_serializer = serializers.get_serializer('json')()
        json_serializer.serialize(bfbw_data, stream=out, indent=4)

    with open("vistours/static/vistours/json/tours.json", "w") as out:
        json_serializer = serializers.get_serializer('json')()
        json_serializer.serialize(tour_data, stream=out, indent=4)

    with open("vistours/static/vistours/json/athlete.json", "w") as out:
        json_serializer = serializers.get_serializer('json')()
        json_serializer.serialize(ath_data, stream=out, indent=4)
    
    return render(request, 'vistours/admin_bookings.html', context)

【问题讨论】:

  • 您可以在显示表单时也添加您的模板代码吗?另外,您是否尝试过删除模型表单中的运动员声明并设置fields = ['asp_booking_ref', 'program_type', 'athlete'] 以查看它是否有效?
  • 感谢 getup8,刚刚尝试过,但字段仍然不显示。然后我需要将运动员字段作为小部件添加为运动员.athlete_name 吗?还添加了上面的模板代码。
  • 您可能还应该添加您的视图代码..(并且可能修复格式)。在模板中,您是否尝试只输入{{ form }} 并查看它是否正确输出?
  • 刚刚添加了我的视图代码。本质上,我们要做的也是首先使用 Booking ID 过滤 ASPBooking,然后使用可用运动员的 Athlete ID 更改运动员 ID(外键)。我希望我不会对此感到困惑,但该计划将允许我们使用此流程将已分配到预订的运动员更改为新运动员。

标签: django django-forms foreign-keys django-widget


【解决方案1】:

感谢您的帮助,我们设法解决了这个问题,使用 JQuery 更改提交按钮链接以添加我们需要的值。

【讨论】:

    猜你喜欢
    • 2015-06-13
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 2017-03-23
    • 2012-12-31
    相关资源
    最近更新 更多