Django Как получить идентификатор из ModelChoiceField? - PullRequest
0 голосов
/ 30 августа 2018

Я новичок в Django и не могу найти решение своей проблемы. Я не знаю, связано ли это с моим пониманием того, как работает Django, или Django не позволяет этого ...

Моя проблема в том, что я не могу получить доступ к значению идентификатора моего объекта "TypeEngine". В моем примере, если я выберу «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 голосов
/ 30 августа 2018

У вас есть запятые в конце ваших назначений, что означает, что вы назначаете кортежи.

Например, у вас есть:

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

Но это должно быть:

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

Однако вам не нужно присваивать поля вручную, как это. Вы можете использовать модель формы , передать 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
}
...
...