Django如何从ModelChoiceField获取ID?

时间:2018-08-30 15:30:54

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

我是Django新手,无法解决我的问题。我不知道这是否与我对Django的工作方式的理解有关,或者Django是否不允许这样做……

我的问题是我无法访问对象“ TypeEngine”的ID值。 在我的示例中,如果我选择“ SQL SERVER”或“ POSTGRES”,则得到的值是“ SQL SERVER”或“ POSTGRES”,但不是1或2。

尝试分配server.type_engine = server_form.cleaned_data['type_engine']时 我有这个错误:

Cannot assign "(<TypeEngine: SQL SERVER 2016 13.0.4001.0>,)": "Server.type_engine" must be a "TypeEngine" instance.

感谢您的帮助!


我的两个模型:

class TypeEngine(models.Model):
    class Meta:
        managed = False
        db_table='type_engine'
    id = models.IntegerField(primary_key=True, db_column='id')
    engine_name = models.CharField(max_length=15, db_column='engine_name')
    engine_version = models.CharField(max_length=15, db_column='engine_version')
    talend_connector_id = models.IntegerField(db_column='talend_connector_id')
    engine_major_version = models.CharField(max_length=15,db_column='engine_major_version')

    def __str__(self):
        return self.engine_name + " " + self.engine_major_version + " " + self.engine_version 

class Server(models.Model):
    class Meta:
        managed = False
        db_table='server'
    id = models.AutoField(primary_key=True, db_column='id')
    name = models.CharField(max_length=200, db_column='server_name')
    ip_address = models.CharField(max_length=15, db_column='server_ip')
    port = models.IntegerField(db_column='server_port')
    user = models.CharField(max_length=50, db_column='user_login')
    type_engine = models.ForeignKey(TypeEngine, on_delete=models.PROTECT, db_column='id_type_engine')
    password = models.BinaryField( db_column='crypted_user_passwd')
    flux = models.BooleanField(db_column='flux')

    def __str__(self):
        return self.name

我有一个对象形式:

class ServerForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(ServerForm, self).__init__(*args, **kwargs)
        self.fields['type_engine'] = forms.ModelChoiceField(queryset=TypeEngine.objects.all(), empty_label=None)
    name = forms.CharField(max_length="200")
    ip_address = forms.CharField(max_length="15")
    port = forms.IntegerField()
    user = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput)
    flux = forms.BooleanField(required=False)

class EditServerForm(ServerForm):
    id = forms.IntegerField(widget=forms.HiddenInput())

然后在我同时启动GET和POST响应的视图中:

def edit(request, id):
    server = Server.objects.get(pk=int(id))
    if request.method == "POST":
        server_form = EditServerForm(data=request.POST or None)
        if server_form.is_valid():
            server.name = server_form.cleaned_data['name'],
            server.ip_address = server_form.cleaned_data['ip_address'],
            server.port = server_form.cleaned_data['port'],
            server.user = server_form.cleaned_data['user'],
            server.type_engine = server_form.cleaned_data['type_engine'],
            server.flux = server_form.cleaned_data['flux']
            server.save() # didn't test it yet
            return redirect('server_details', id=server.id)
    else:
        serverform_context = {
            'id': server.id,
            'name': server.name,
            'ip_address': server.ip_address,
            'port': server.port,
            'user': server.user,
            'password': server.password,
            'type_engine': server.type_engine,
            'flux': server.flux
        }
        server_form = EditServerForm(initial=serverform_context)

    context = {
        'server_form': server_form
    }
    template = loader.get_template('referential/Server/Edit.html')
    return HttpResponse(template.render(context, request=request))

我的模板:

{% extends 'referential/base.html' %}
{% load static %}
{% block title %}
    <h1>Modification d'un serveur</h1>
{% endblock %}
{% block content %}
    <form method="POST" action="{% url 'server_edit' id=server_form.id.value %}" >
        <div class="form-horizontal">
            <div class="form-group">
                <div class="col-md-6">
                    {{ server_form.id }}
                    {% if server_form.id.errors %}
                        {% for error in server_form.id.errors %}
                            <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.id.id_for_label }}" data-valmsg-replace="true">{{ error }}</span>
                        {% endfor %}
                    {% endif %}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.name.id_for_label }}">{{ server_form.name.label }}</label>
                <div class="col-md-6">
                    {{ server_form.name }}
                    {% if server_form.name.errors %}
                        {% for error in server_form.name.errors %}
                            <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.name.id_for_label }}" data-valmsg-replace="true">{{ error }}</span>
                        {% endfor %}
                    {% endif %}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.ip_address.id_for_label }}">{{ server_form.ip_address.label }}</label>
                <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.ip_address.id_for_label }}" data-valmsg-replace="true">{{ server_form.ip_address.errors }}</span>
                <div class="col-md-6">
                    {{ server_form.ip_address }}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.port.id_for_label }}">{{ server_form.port.label }}</label>
                <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.port.id_for_label }}" data-valmsg-replace="true">{{ server_form.port.errors }}</span>
                <div class="col-md-6">
                    {{ server_form.port }}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.user.id_for_label }}">{{ server_form.user.label }}</label>
                <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.user.id_for_label }}" data-valmsg-replace="true">{{ server_form.user.errors }}</span>
                <div class="col-md-6">
                    {{ server_form.user }}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.password.id_for_label }}">{{ server_form.password.label }}</label>
                <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.password.id_for_label }}" data-valmsg-replace="true">{{ server_form.password.errors }}</span>
                <div class="col-md-6">
                    {{ server_form.password }}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.type_engine.id_for_label }}">{{ server_form.type_engine.label }}</label>
                <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.type_engine.id_for_label }}" data-valmsg-replace="true">{{ server_form.type_engine.errors }}</span>
                <div class="col-md-6">
                    {{ server_form.type_engine }}
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-md-2" for="{{ server_form.flux.id_for_label }}">{{ server_form.flux.label }}</label>
                <span class="field-validation-error text-danger" data-valmsg-for="{{ server_form.flux.id_for_label }}" data-valmsg-replace="true">{{ server_form.flux.errors }}</span>
                <div class="col-md-6">
                    {{ server_form.flux }}
                </div>
            </div>

            {% csrf_token %}
            <button type="submit" class="save btn btn-default">Save</button>
        </div>
    </form>
{% endblock %}

填充数据的示例:

<select name="type_engine" id="id_type_engine">
     <option value="1">SQL SERVER 2016 13.0.4001.0</option>
     <option value="2">POSTGRES</option>
</select>

1 个答案:

答案 0 :(得分:0)

分配的末尾有逗号,这表示您正在分配元组。

例如,您有

server.type_engine = server_form.cleaned_data['type_engine'],

但是应该是:

server.type_engine = server_form.cleaned_data['type_engine']

但是,您不需要像这样手动分配字段。您可以使用model form,在实例化表单时传递instance,然后在有效时保存表单。

server = Server.objects.get(pk=int(id))
if request.method == "POST":
    server_form = EditServerForm(data=request.POST, instance=server)
    if server_form.is_valid():
        server = server_form.save()
        return redirect(...)
else:
    server_form = EditServerForm(instance=server)
context = {
    'server_form': server_form
}
...