I'm trying to make a manytomany field from a model that is not the model that the manytomany field will contain a list of. e.g.
class Following(models.Model):
following_id = models.AutoField(primary_key=True)
following_user = models.ForeignKey(User, models.DO_NOTHING, related_name="following_user")
following = models.ManyToManyField(User, related_name="following")
This looks all good to me, but when I try to enter the shell and do something like User.following.add(OtherUser), I get an error saying that it was expecting OtherUser to be an instance of Following. Why is this? Did I not specify that the ManyToManyField was storing User instances when I declared the following variable?
models.ManyToManyField(**User**, related_name="following")
1 - Create a user : user = User(); user.save()
2 - Create a following : following = Following(); following.save()
3 - Add the user to the following : following.following.add(user)
You can reference a model with other model only once. But you are using User model two times, one with following_user field and other with following field. Look below your model.
class Following(models.Model):
following_id = models.AutoField(primary_key=True)
following_user = models.ForeignKey(*User*, models.DO_NOTHING, related_name="following_user")
following = models.ManyToManyField(*User*, related_name="following")
try this:
Another side effect of using commit=False is seen when your model has a many-to-many relation with another model. If your model has a many-to-many relation and you specify commit=False when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn’t possible to save many-to-many data for an instance until the instance exists in the database.
To work around this problem, every time you save a form using commit=False, Django adds a save_m2m() method to your ModelForm subclass. After you’ve manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data. For example:
Related
Is there a way to add a field to a Django model class such that:
It doesn't get persisted to the database (i.e. no column in the DB)
It does get rendered by a ModelForm
The widget for that field can be customised
I believe 3. can be done with a custom widget, and 2. will happen if the field inherits from models.Field. However, I haven't found a way to achieve 1. without breaking 2. and 3. I was hoping for a persist=False or db_column=None type of solution.
Scenario:
I'm using this to quickly produce data capture forms by only adding a class to the model, but in order to insert headers for sub sections I still having to edit the template. Was hoping to do the following:
models.py
from django.db import models
class Applicant(models.Model):
sectionA = models.SectionField(help_text="Personal details")
title = models.CharField(max_length=100)
name = models.CharField(max_length=100)
sectionB = models.SectionField(help_text="Banking details")
account = models.CharField(max_length=100)
pin = models.CharField(max_length=100)
In the above example, sectionA and sectionB are instances of a custom model.Field that doesn't actually get persisted but cause a heading to be rendered by the ModelForm and a custom widget
Finally:
I realise this probably violates separation of View and Model.
Other questions have been asked about non-persisting fields but their solutions don't render in a ModelForm
Sort of, Just don't make them a model field, theres no need for them to be.
sectionA = "Personal details"
sectionB = "Banking details"
You can access them via form.instance where you need them, you could even make them a form field instead of a string as I've shown here.
I have a Django Model with ManyToManyField in it. I need to require user to select at least one M2M value in this field.
I tried to set blank=False to M2M field but it didn't help.
class Skill(models.Model):
name = models.CharField(max_length=200)
class PersonSkills(models.Model):
person = models.ForeignKey('Person')
skill = models.ForeignKey('Skill')
class Person(models.Model):
name = models.CharField(max_length=200)
skills = models.ManyToManyField('Skill', through='PersonSkills')
p = Person(name='Bob')
p.save()
# success, but I expect that this should throw ValidationError, because I didn't select at least one Skill for this person
I can solve this situation with custom Form definition or with override save() method for Person model.
Is it possible to prevent create Person without at least one Skill selected, with set ManyToManyField options? Or I need to create custom logic to handle this situation? Thanks.
I use Django 1.7 and Python 3.4
Update 1. How to create ModelForm to control M2M? Because in cleaned_data I have only fields that I pass for Person form, and haven't data that I pass as M2M fields. I try to create object in Admin Site and control that Skills selected. I enter Skill's via inline.
# admin.py
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
extra = 2
class PersonAdmin(admin.ModelAdmin):
inlines = [PersonSkillsInline]
admin.site.register(Person, PersonAdmin)
On a database level... no, that's not possible. Any enforcement of this will have to come from your application logic.
The reason is that every m2m relation has a record with a foreign key to both sides of the m2m relation. SQL cannot enforce the existence of the referencing side of a relationship, only of the referenced side of a relationship.
Furthermore, you can't enforce it in your model either, because the Person has to be created and saved before you can assign any many-to-many relations.
Your only options are to enforce it in the form or the view.
In an InlineModelAdmin this can easily be done by specifying min_num (1.7+):
class PersonSkillsInline(admin.TabularInline):
model = Person.skills.through
min_num = 1
extra = 2
I have a form in Django called PersonForm this forms model has a one-to-many relationship with Car. When displaying the PersonForm just like in the Django Admin I would like to allow my users to select/deselect from a list of Cars etc. Is this possible? I'm looking for information on where to start.
This is what I have so far for the PersonForm:
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('description',)
The Models:
class Person(models.Model):
description = models.CharField(max_length="150")
class Car(models.Model):
make = models.CharField(max_length="25")
owner = models.ForeignKey('Person', related_name="Car")
So in the person form I need to show a list of cars that person is the owner of an allow selecting/deselecting of them. I'm assuming I can do this in the form i.e. using something like the related name.
Sounds like you want an inline model form. This give you the ability to add/remove Car objects from a Person within the Person form.
That previous link was for inlinemodeladmin. This next link is for an inline form:
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelforms-factory
I didn't have any chance with inline formset, so i would suggest to override your save method of the model, i feel it's more DRY:
class PersonForm(forms.ModelForm):
# add a field to select a car
car = forms.ModelChoiceField(car.objects.all())
class Meta:
model = Person
fields = ('description', 'car')
def save(self, commit=True):
instance = super().save(commit)
# set Car reverse foreign key from the Person model
instance.car_set.add(self.cleaned_data['car']))
return instance
I know this is an old thread, but since I found myself almost exclusively pointed here by google when searching, I thought I would include the following for anyone else looking for an answer.
The answer, I think, is to use
https://docs.djangoproject.com/en/3.1/ref/forms/fields/#modelchoicefield
or
https://docs.djangoproject.com/en/3.1/ref/forms/fields/#modelmultiplechoicefield
There is a good article on how to use the modelmultiplechoicefield at :
https://medium.com/swlh/django-forms-for-many-to-many-fields-d977dec4b024
But it works for one to many fields as well. These allow us to generate a form with multiple choices as checkboxes or similar widgets based upon a related field in a model.
I have a model MyModel2 with a ManyToManyField related to another model MyModel1.
How can I get the pairs mymodel1.id, mymodel2.id, as represented in the table Django creates for this relation? Do I have to do a raw SQL query on this table or is it possible through the object managers of this models?
class MyModel1(models.Model):
name = models.CharField(max_length=50)
class MyModel2(models.Model):
name = models.CharField(max_length=50)
mymodel1 = models.ManyToManyField(MyModel1)
This is the many to many field instance:
MyModel2.mymodel1
This is the intermediary table model:
MyModel2.mymodel1.through
This is the intermediary model manager:
MyModel2.mymodel1.through.objects
This returns a queryset for all intermediary models:
MyModel2.mymodel1.through.objects.all()
This part of django docs talk about through. You can make a through model yourself, else it is automatically generated.
I've defined a models.py with a "FirstClass" which contains a ForeignKey relathionship to "SecondClass". The relathionship can't be Null.
The SecondClass is very expansive (90.000 records), and when i display the FirstClass html form, it requires too many time generating the "select box" field.
Therefore, when I let user update the object (I use create_update.update_object generic view), i don't want to display and update the value of the foreignkey field, but i don't know how to do this...
Create a ModelForm and pass it into the view, according to the docs.
Since the foreign key should always exist upon creation, it's safe to ignore it in the update.
class MyModelForm(forms.ModelForm):
class Meta:
model = FirstClass
exclude = ('SecondClass',)
# urls.py
(r'^foo/(?P<object_id>\d+)/$','django.views.generic.create_update.update_object',
{'form_class': MyModelForm})