0

How can I create a relationship between my object and foreign key from a form submit? You can skip down to the very last line of code to see my issue.

edit

My user will not have an option to select the related model object. The related model object will be exclusively the one identified by the id which is determined from the URL, i.e. domain.com/myview/100

models.py

class Activity(models.Model):
    id = models.AutoField(primary_key=True)

class Contact(models.Model):
    id = models.AutoField(primary_key=True)
    firstname = models.CharField(max_length=100, null=False, blank=False)
    activity = models.ManyToManyField(Activity, blank=True)

forms.py

class ContactForm(forms.ModelForm):
    firstname = forms.CharField(max_length=100,
        widget=forms.TextInput(attrs={'placeholder':'John'}))

    class Meta:
        model = Contact

views.py

def index(request, id=None):
    if id:
        if request.method == 'POST':
            contact_form = ContactForm(request.POST)
            if contact_form.is_valid():
                contact = contact_form.save()
                # link contact to activity here, activity pk is 'id'
smilebomb
  • 5,123
  • 8
  • 49
  • 81
  • By the way, you don't need `id` field in the model, it's automatically generated. Django model is not relational database design. – Shang Wang Aug 02 '16 at 19:12
  • @ShangWang What do you mean already in the form? Django may automatically create an ID, I can't remember. Shouldn't hurt to explicitly define it though. – smilebomb Aug 02 '16 at 19:14
  • Possible duplicate of [Django ModelForm for Many-to-Many fields](http://stackoverflow.com/questions/2216974/django-modelform-for-many-to-many-fields) – Shang Wang Aug 02 '16 at 19:14
  • Sorry I misread your code, but I think it's been asked before. I'm just saying it's not necessary to have `id` as a field because django developers don't usually do that, just like python developers don't use `i` as index to loop a list. – Shang Wang Aug 02 '16 at 19:16
  • @ShangWang My user will not have the option to select from model objects. The model to be linked is exclusively the `id`, which is access from the URL. I don't think my form will have a way to get a value from my URL. – smilebomb Aug 02 '16 at 19:17
  • @ShangWang that's right, I don't want to do that. The activity is already defined. Contacts will be added, and when they validate, they will be associated with the `activity` defined by the `id` of the `URL` from which they submitted the form. – smilebomb Aug 02 '16 at 19:22

1 Answers1

2

I finally see what are you trying to do, it's pretty easy:

contact = contact_form.save()
# link contact to activity here, activity pk is 'id'
activity = Activity.objects.get(id=id)
contact.activity.add(activity)

I was confused before because you have id as view function parameter, which people usually use to update a contact because you also have a ContactForm in views.py method. You might make it more explicit using activity_id instead, and make the function name more explicit as well.

Shang Wang
  • 24,909
  • 20
  • 73
  • 94
  • Yes, thank you. I forgot the syntax and it's always a pain to find these one-off things in the django docs, especially since I'm not on the latest version. Thank you for your patience. – smilebomb Aug 02 '16 at 19:28