Hi i'm using ModelFieldChoice to set the foreign key from Provider in the model "Article" (Article belongs to Provider). The select in the template is displayed correctly with all the providers from the database, but when i try to post the form, it throws an error that the select value is required even if i'm passing it. Also i seted values for the article in the database, and when i tried to edit it, all the fields in the form are populated with the correct data except for the select. These are my models, i would appreciate the help, thanks! Sorry if i'm doing something wrong, this is my first time posting in stackoverflow. Article.py Model
class Article(models.Model):
codigo = models.CharField(max_length=100, verbose_name='Codigo')
proveedor = models.ForeignKey(Provider, on_delete=models.CASCADE)
descripcion = models.CharField(max_length=200, verbose_name='Descripcion',null=False, blank=True)
marca = models.CharField(max_length=100, verbose_name='Marca',null=True, blank=True)
rubro = models.CharField(max_length=100, verbose_name='Rubro',null=True, blank=True)
nota = models.TextField(verbose_name='Nota',null=True)
costo = models.CharField(max_length=50, verbose_name='Costo',null=False, blank=True)
created = models.DateTimeField(auto_now_add=True, verbose_name="Fecha de creación",null=True, blank=True)
updated = models.DateTimeField(auto_now=True, verbose_name="Fecha de edición",null=True, blank=True)
class Meta:
verbose_name = "articulo"
verbose_name_plural = "articulos"
ordering = ['-descripcion']
def __str__(self):
return self.descripcion
Provider.py Model
class Provider(models.Model):
razon_social = models.CharField(max_length=100, verbose_name='Razón Social', unique=True)
direccion = models.CharField(max_length=100, verbose_name='Dirección', blank=True, null=True)
localidad = models.CharField(max_length=100, verbose_name='Localidad', blank=True, null=True)
provincia = models.CharField(max_length=100, verbose_name='Provincia', blank=True, null=True)
telefono = models.CharField(max_length=100, verbose_name='Teléfono', blank=True, null=True)
mail = models.CharField(max_length=100, verbose_name='Email', blank=True, null=True)
web = models.CharField(max_length=100, verbose_name='Sitio Web', blank=True, null=True)
created = models.DateTimeField(auto_now_add=True, verbose_name="Fecha de creación", null=True)
updated = models.DateTimeField(auto_now=True, verbose_name="Fecha de edición", null=True)
class Meta:
verbose_name = "proveedor"
verbose_name_plural = "proveedores"
ordering = ['-razon_social']
def __str__(self):
return self.razon_social
form.py (ArticleCreate)
class ArticleCreate(forms.ModelForm):
proveedor_id = forms.ModelChoiceField(queryset=Provider.objects.none(), empty_label="Elegir un proveedor")
class Meta:
model = Article
fields = '__all__'
def __init__(self, *args, **kwargs):
super(ArticleCreate, self).__init__(*args, **kwargs)
self.fields['proveedor_id'].queryset = Provider.objects.all()
views.py
def add_article(request):
if request.method == 'POST':
create = ArticleCreate(request.POST)
print(request.POST['proveedor_id'])
if create.is_valid():
create.save()
return redirect('/dashboard/articles/?add=success')
else:
print(create.errors)
return redirect('/dashboard/articles/?error=True')
else:
return render(request, "article/add_edit_article.html", {'editMode': False,'form': ArticleCreate})
In views.py when i print 'proveedor_id' the value is correctly displayed in console but then the "is_valid()" fails and it prints the error "<ul class="errorlist"><li>proveedor<ul class="errorlist"><li>Este campo es obligatorio.</li></ul></li></ul>"
(obligatory field, as if i'm not passing it)
First, simplify your ArticleCreate
serializer to be like this:
class ArticleCreate(forms.ModelForm):
class Meta:
model = Article
Then in the request pass proveedor
field, not proveedor_id
. In Django/DRF you should pass association IDs using "{{association_name}}": id
pattern, not "{{association_name}}_id": id
Sou you can simplify your view as well:
def add_article(request):
if request.method == 'POST':
create = ArticleCreate(request.POST)
if create.is_valid():
create.save()
...