Отправить форму Django с внешним ключом

#python #django #django-models #django-forms #foreign-keys

#python #django #django-модели #django-forms #внешние ключи

Вопрос:

Я пытаюсь отправить форму, которая добавила бы новый «элемент» / строку в мой список таблиц, используя Django.

Я уверен, что проблема заключается в том, что я использую ForeignKey и продолжаю получать следующую ошибку :

 ValueError: Cannot assign "'2'": "Listing.category" must be a "Category" instance.
  

Обратите внимание, что значение 2 выше — это всего лишь один из 7 вариантов, которые у меня есть.

Моя таблица «Категория», определенная в Models.py в настоящее время заполняется следующим образом:

 (id) : (category)
    7 : Book
    6 : Technology
    5 : Beauty
    4 : Clothing
    3 : Health
    2 : Sports
    1 : Grocery
  

Models.py :

 class Category(models.Model):
    category = models.CharField(max_length=16)
    
    def __str__(self):
        
        return f"{self.id} : {self.category}"

class Listing(models.Model):
    owner = models.CharField(max_length=64)
    title = models.CharField(max_length=64)
    description = models.CharField(max_length=256)
    startingBid = models.IntegerField()
    link = models.CharField(max_length=1024,blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category_id")
    time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'"{self.title}" added by {self.owner}'
  

Views.py

     class Create(forms.Form):
        CHOICES = (
            (1, 'Grocery'),
            (2, 'Sports'),
            (3, 'Health'),
            (4, 'Clothing'),
            (5, 'Beauty'),
            (6, 'Technology'),
            (7, 'Book'),
        )
        owner = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Your Username'}))
        title = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'What is your item?'}))
        description = forms.CharField(widget=forms.Textarea(attrs={'placeholder': 'Max 256 characters'}))
        link = forms.URLField(required=False)
        startingBid = forms.IntegerField()
        category = forms.ChoiceField(choices=CHOICES)
    
    @login_required
    def create_listing(request):
        if request.method == "POST":
            form = Create(request.POST)
            if form.is_valid():
                owner = form.cleaned_data["owner"]
                title = form.cleaned_data["title"]
                description = form.cleaned_data["description"]
                link = form.cleaned_data["link"]
                startingBid = form.cleaned_data["startingBid"]
                category = form.cleaned_data["category"]
    
                item = Listing(owner=owner, title=title, description=description, link=link, startingBid=startingBid, category=category)
                item.save()
    
        else:
            return render(request, "auctions/create_listing.html", {
                    "create": Create()
                    })
  

В целях устранения неполадок я вручную жестко запрограммировал идентификатор или английское слово для категории вместо передачи category=категория (например, category=’Sports’ или category =’4′), но это не помогает.

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

Я уверен, что моя проблема довольно проста, но, похоже, я не могу понять основную причину проблемы.

С нетерпением ждем вашей помощи!

Ответ №1:

Попробуйте это:

 item = Listing(owner=owner, title=title, description=description, link=link, startingBid=startingBid, category_id=category)
  

Категория ожидает объект, в то время как вы передаете идентификатор, поэтому category_id следует выполнить трюк, если то, что вы передаете, является его идентификатором.

Если вы передаете выбор категории, то вам следует попробовать:

 item = Listing(owner=owner, title=title, description=description, link=link, startingBid=startingBid, category__category=category)
  

Ответ №2:

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

Попробуйте это:

 category = Category.object.filter(id = form.cleaned_data["category"]).first()

item = Listing(owner=owner, title=title, description=description, link=link, startingBid=startingBid, category=category)