Search code examples
pythondjangomany-to-many

Django m2m relationship problems


i'm not expert in django, so sorry if this question seems stupid. I'm trying to create a simple register page in django and i'm getting some problems with many-to-many relationship.

My models.py

class Dog(models.Model):
    name = models.CharField(max_length=100)
    reg_num = models.CharField(max_length=100)
    owner = models.ManyToManyField('Owner', db_column='owner')

    class Meta:
        managed = False
        db_table = 'dog'

    def __str__(self):
        return self.name


class Owner(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

I'm using class based views from django:

class DogForm(ModelForm):
    class Meta:
        model = Controle
        fields = ['name', 'reg_num','owner']

class DogMixin(object):
    model = Dog
    form_class = DogForm
    template_name = 'generic_form.html'
    success_url = reverse_lazy('dog_list')


    def form_valid(self, form):
        obj = form.save(commit=False)
        obj.user = self.request.user
        obj.save()        
        return HttpResponseRedirect(self.success_url)


class DogCreate(DogMixin, CreateView):
    pass

class DogUpdate(DogMixin, UpdateView):
    pass

class DogDelete(DogMixin, DeleteView):
    template_name = 'generic_delete.html'

And finally the html file:

            <tbody>
            {% for dog in object_list%}
            <tr>
                <td> {{dog.name}}</td>
                <td> {{dog.reg_num}}</td>
                <td> {{dog.owner}}
            </tr>
            {% endfor %}
    </tbody>

When i create the dog instance, i select the owner in a box. The table is ok, except the "dog.owner" it appears as None. What am i missing?


Solution

  • You're assigning dog.user in your view, but the field is called owner.

    However, I don't think that you want a many-to-many field here. That would imply that a dog has many owners, and would also mean that you would need to iterate over dog.owner.all in your template. I think instead you want a simple ForeignKey, in which case you can do dog.owner = self.request.user and then output it as you are already doing.

    Edit If you're sure, then you need to add the current user to the list of owners: dog.owner.add(self.request.user). And, as I say, in your display template you can't just show "the owner" because there are many: you need to iterate over dog.owner.all and show the name of each one.