Django ForeignKey Модель Форма - PullRequest
       17

Django ForeignKey Модель Форма

0 голосов
/ 28 ноября 2018

Я новичок на Джанго.У меня есть две модели, и одна из этой модели имеет внешний ключ.Я использую форму модели в формах, и когда я заполняю форму, поле внешнего ключа возвращает значение null.Что я хочу, чтобы при заполнении поля внешнего ключа формы, заполнить в соответствии с указанным внешним ключом.

Модели:

class customerInfo(models.Model):
customerName = models.CharField(max_length = 50)
customerContent = models.TextField(max_length = 50)
createdDate= models.DateTimeField(auto_now_add = True)

def __str__(self):
    return self.customerName

class productInfo(models.Model):
    username = models.CharField(max_length = 50)
    passwd = models.CharField(max_length = 50)
    destIp = models.CharField(max_length = 50)
    hostname = models.CharField(max_length = 50)
    productName = models.CharField(max_length = 50)
    customer = models.ForeignKey(customerInfo,on_delete = models.CASCADE,null=True)

    def __str__(self):
        return self.productName

Формы:

class customerForm(forms.ModelForm):
    class Meta:
        model = customerInfo
        fields = (
                "customerName",
        )

    class addProductForm(forms.ModelForm):
        class Meta:
            model = productInfo
            fields = (
                    "productName",
                    )


    class productInfoForm(forms.ModelForm):
            class Meta:
                    model = productInfo
                    fields = (
                            "username",
                            "passwd",
                            "destIp",
                            "hostname",
                    )

Просмотры:

@login_required(login_url = "/")
def addCustomer(request):
    form = customerForm(request.POST or None)
    content = {"form" : form,}
    if form.is_valid():
        form.save()
        customerName = form.cleaned_data['customerName']
        return redirect("addproduct")

    else:
        return render(request,"addcustomer.html",content)

@login_required(login_url = "/")
def addProduct(request):
    form = addProductForm(request.POST or None)
    content = {"form" : form}
    if form.is_valid():
        global productName
        productName = form.cleaned_data['productName']
        return redirect("addproductinfo")
    return render(request,"addproduct.html",content)

@login_required(login_url = "/")
def addProductInfo(request):
    form = productInfoForm(request.POST or None)
    content = {"form" : form}
    if form.is_valid():
        p = form.save(commit = False)
        p.productName = productName
        p.save()
        return redirect("customer")
    return render(request,"addproductinfo.html",content)

В результате я хочу видеть продукты клиента, когда нажимаю на имя клиента.Не все продукты.Прежде чем я смогу это сделать, поля идентификатора клиента должны быть заполнены.Надеюсь, вы меня поняли.

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Ваш вопрос и пример кода не понятны.Прежде всего следует разбить модель на несколько вариантов использования:

  • Клиент: список клиентов, клиент Создать, прочитать, обновить и удалить (CRUD)
  • Продукт: списокproducts, Create, Read, Update & Delete (CRUD) product

Из списка клиентов вы можете прочитать одно, а в «подробном представлении» вы можете создать, обновить или удалить его.

Из списка продуктов вы можете прочитать один, а в «представлении подробностей» вы можете создать, обновить или удалить его.

Можно выполнить переход от списка клиентов к списку продуктов.с помощью дополнительной кнопки / ссылки, отображаемой на каждой строке в вашем списке клиентов, чтобы ваша кнопка / ссылка использовалась для отображения любых сведений о клиенте.

PrimaryKey (PK) клиента передается в детали через определение URL.

path('customer/<pk>', views.customer_detail_view, name='customer_detail'),

Этот URL предназначен только для отображения.Вам также нужен один для каждой операции БД: создание, обновление, удаление.Ниже приведен пример кода urls.py для вашего клиента.Для продуктов вам понадобится то же самое.

from django.urls import path
from . import views

urlpatterns = urlpatterns + [
    path('customer', views.customer_list_view, name='customer_list'),
    path('customer/add', views.customer_add_view, name='customer_add'),
    path('customer/<pk>', views.customer_detail_view, name='customer_detail'),
    path('customer/<pk>/upd', views.customer_update_view, name='customer_update'),
    path('customer/<pk>/del', views.customer_delete_view, name='customer_delete'),
    ]

Обратите внимание, что create не передает 'pk', поскольку оно пока неизвестно ...

Вызов в подробном представлении изпредставление списка выполняется в вашем html-шаблоне

<tbody>
{% for i in customer_list %}
<tr>
  <td><a href="{% url 'customer_detail' pk=i.id %}">{{ i.customerName }}</a></td>
  <td>{{ i.customerContent|default_if_none:"" }}</td>
</tr>
{% endfor %}
</tbody>

Аргумент передается через kwargs (dict) через URL, и если вы используете ClassBasedView (generic.DetailView), он будет обработан автоматически.Если нет, вам нужно взять kwargs, например: kwargs.get('pk') or kwargs.pop('pk') последний удаляет pk из kwargs.Вы также можете передать 'pk' используя args (без назначения ключа pk) {% url 'customer_detail' i.id %}.Это также может быть определено непосредственно в функции get_absolute_url вашей модели.def get_absolute_url (self): вернуть reverse_lazy ('customer_detail', args = [str (self.id)]) или def get_absolute_url (self): вернуть reverse_lazy ('customer_detail', kwargs = {'pk': self.pk})

Поступая таким образом, вы также сможете управлять своей глобальной переменной productName, чего следует избегать!Кстати, я не понимаю, почему вы готовы разделить создание productName и productInfo ???Почему бы не хранить их все вместе?

Наконец, если вы хотите отобразить несколько возможных строк кодирования для вашего Продукта, вам следует взглянуть на Django-FormSet .Поищите в Google учебник по FormSet, но это более продвинутая функция.

ProductFormset с 5 возможными строками кодирования будет выглядеть следующим образом:

from django.forms import modelformset_factory

ProductFormset = modelformset_factory(
    productInfo,
    fields=('productName', ),
    extra=5,
    widgets={'name': forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter product Name here'
        })
    }
)
0 голосов
/ 28 ноября 2018

Если вы хотите повторно использовать модель productInfo, вы должны указать свои модели.ManyToManyField вместо ForeignKey.Как я правильно понимаю, вы хотите иметь продукт, к которому несколько клиентов могут «подключиться», верно?

для получения дополнительной информации -> https://docs.djangoproject.com/en/2.1/ref/models/fields/

и более -> https://www.revsys.com/tidbits/tips-using-djangos-manytomanyfield/

Мое использование:

class EventVocab(models.Model):
    word              = models.CharField(max_length = 30)
    word_chinese      = models.CharField(max_length = 30,blank=True, null=True)
    explanation       = models.TextField(max_length = 200)
    example           = models.TextField(max_length = 100)
    word_audio        = models.FileField(blank=True, null=True)
    explanation_audio = models.FileField(blank=True, null=True)
    example_audio     = models.FileField(blank=True, null=True)

class UserVocab(models.Model):
    event_vocab  = models.ManyToManyField(EventVocab, related_name='event_vocab')
    current_user = models.ForeignKey(User, related_name="vocab_owner", on_delete=models.CASCADE)

В этом примере UserVocab (в вашем случае продукт) может быть подключен только к одному пользователю, но один пользователь может иметь несколько event_vocabs(продукты)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...