'ManyToManyField' queries - django

I'm advancing with the web app I asked about earlier.
Currently, my models.py is
from django.db import models
from unittest.util import _MAX_LENGTH
class Alimento(models.Model):
INTOLERANCIAS = (
('00', 'Ninguna'),
('GL', 'Gluten'),
('CR', 'Crustáceos'),
('HU', 'Huevos'),
('FS', 'Frutos Secos'),
('AP', 'Apio'),
('MO', 'Mostaza'),
('SE', 'Sésamo'),
('PE', 'Pescado'),
('CA', 'Cacahuetes'),
('SO', 'Sulfitos'),
('SJ', 'Soja'),
('LA', 'Lácteos'),
('AL', 'Altramuz'),
('ML', 'Moluscos'),
('CA', 'Cacao'),
)
nombre = models.CharField(max_length=60)
intolerancia = models.CharField(max_length=2, choices=INTOLERANCIAS)
def __str__(self):
return self.nombre
class Receta(models.Model):
nombre = models.CharField(max_length=100)
raciones = models.IntegerField(default=1)
preparacion = models.TextField(default='')
consejos = models.TextField(blank=True)
ingredientes = models.ManyToManyField(Alimento, through='Ingrediente', related_name='ingredientes')
def __str__(self):
return self.nombre
def getIntolerancias(self):
ing = self.ingredientes.all()
intolerancias = []
for i in ing:
alimentos = i.alimento.all()
for a in alimentos:
intolerancias.append(a.get_intolerancia_display())
return intolerancias
class Ingrediente(models.Model):
receta = models.ForeignKey('recetas.Receta', on_delete=models.CASCADE)
alimento = models.ManyToManyField(Alimento)
cantidad = models.FloatField(default=0)
descripcion = models.CharField(max_length=60, blank=True)
def __str__(self):
return self.alimento.__str__()
the method getIntolerancias is supposed to list the food intolerances related to each of the ingredients of a given recipe (Receta). To do that, I try to get the queryset of ingredients (Ingrediente) with ing = self.ingredientes, but when I try it on shell I get this error message
Traceback (most recent call last): File "/usr/lib/python3.5/code.py", line 91, in runcode
exec(code, self.locals) File "<console>", line 1, in <module> File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 476, in __get__
return self.related_manager_cls(instance) File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 758, in __init__
self.target_field_name = rel.field.m2m_reverse_field_name() File "/usr/local/lib/python3.5/dist-packages/django/utils/functional.py", line 15, in _curried
return _curried_func(*(args + moreargs), **dict(kwargs, **morekwargs)) File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related.py", line 1504, in _get_m2m_reverse_attr
return getattr(self, cache_attr) AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'
I've searched for the error, but the answers I've found don't seem to have what I need (I may just don't understand enough to see it does?)
UPDATE
When I run this on the shell I do
g = Receta.objects.get(nombre = 'Gazpacho')
g.getIntolerancias()
I get an error
intolerancias.append(a.get_intolerancia_display()) AttributeError:
'Ingrediente' object has no attribute 'get_intolerancia_display'
However, if I iterate and get the first element of g.ingredientes.all() and call get_intolerancia_display() it does work OK
a = g.ingredientes.all().first()
a.get_intolerancia_display()
'Gluten'

Update after comments:
Documentation about Many-to-many relation
def get_intolerancias(self):
alimentos = self.ingredientes.all() # Give us all alimento of a recetta
intolerancias = []
for a in alimentos:
intolerancias.append(a.get_intolerancia_display())
return intolerancias

Related

Original exception text was: 'int' object has no attribute 'name'. in django rest framework

I am trying to call a get api but it gives me this error everytime.
The error:
AttributeError: Got AttributeError when attempting to get a value for field name on serializer NestedSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the int instance.
Original exception text was: 'int' object has no attribute 'name'.
My models:
class Destination(models.Model):
Continent_Name = (
('Europe', 'Europe',),
('Asia', 'Asia',),
('North America', 'North America',),
('South America', 'South America',),
('Africa', 'Africa',),
('Oceania', 'Oceania',),
('Polar', 'Polar',),
('Regions', 'Regions',),
)
name = models.CharField(max_length=255, unique=True)
continent = models.CharField(max_length=255, choices=Continent_Name, default='Europe')
top = models.BooleanField(default=False)
dest_image = models.ImageField(blank=True)
def __str__(self):
return self.name
class Package(models.Model):
TOUR_TYPE = (
('Custom-made trip with guide and/or driver', 'Custom-made trip with guide and/or driver',),
('Custom-made trip without guide and driver', 'Custom-made trip without guide and driver',),
('Group Tour', 'Group Tour',),
('Cruise Tour', 'Cruise Tour',),
)
operator = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
destination = models.ForeignKey(Destination, on_delete=models.CASCADE)
package_name = models.CharField(max_length=255)
city = models.CharField(max_length=255)
featured = models.BooleanField(default=False)
price = models.IntegerField(verbose_name="Price in Nrs")
price_2 = models.IntegerField(verbose_name="Price in $")
duration = models.IntegerField(default=5)
duration_hours = models.PositiveIntegerField(blank=True,null=True,verbose_name="Hours If One day Tour")
discount = models.IntegerField(verbose_name="Discount %", default=15)
#discounted_price = models.IntegerField(default=230)
#savings = models.IntegerField(default=230)
tour_type = models.CharField(max_length=100, choices=TOUR_TYPE, default='Group Tour')
new_activity = models.ManyToManyField(NewActivity)
accommodation = models.CharField(max_length=255, default='Guest House & Hotel')
transport = models.CharField(max_length=150, default='Flight')
age_range = models.CharField(max_length=100, default='6 to 79 years old')
fix_departure = models.BooleanField(default=False)
rating = models.IntegerField(choices=((1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5))
)
image = models.ImageField(blank=True, verbose_name="Thumbnail Image-Vertical")
content =RichTextField()
highlights = RichTextField()
inclusions = RichTextField()
exclusions = RichTextField()
# itinerary = models.ManyToManyField(Itinerary)
itinerary_text = RichTextField()
faqs = RichTextField(blank=True)
image_1= models.ImageField(blank=True,null = True,verbose_name="Image-Horizontal")
image_2= models.ImageField(blank=True,null = True,verbose_name="Image-Square")
image_3= models.ImageField(blank=True,null = True,verbose_name="Image-Sqaure")
date_created = models.DateField()
def __str__(self):
return self.package_name
My views:
class PackageSearchAPi(ListAPIView):
queryset = Package.objects.all().order_by('package_name')
serializer_class = PackageSerializer
def get(self, request, *args, **kwargs):
search = self.request.query_params.get('search',None)
if search is not None:
qs = Package.objects.filter(Q(destination__name__icontains=search)|
Q(destination__continent__icontains=search)|
Q(package_name__icontains=search)|
Q(city__icontains=search)).disctinct()
else:
qs = Package.objects.values('id','destination','package_name','city')
serializer = PackageSerializer(qs,many=True)
return Response(serializer.data,status=200)
My serializers:
class PackageSerializer(serializers.ModelSerializer):
class Meta:
model = Package
fields = ['id', 'operator','destination', 'package_name', 'duration', 'featured', 'price','price_2', 'discount',
'city', 'tour_type','new_activity', 'accommodation', 'transport', 'age_range',
'fix_departure', 'rating', 'image', 'date_created', ]
depth = 1
Here I checked the code and nothing seems to be wrong in any part but keeps getting the same above error.
Traceback:
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Saroj\Desktop\TravelCRM\apps\packages\views.py", line 251, in get
return Response(serializer.data,status=200)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\serializers.py", line 760, in data
ret = super().data
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\serializers.py", line 677, in to_representation
return [
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\serializers.py", line 678, in <listcomp>
self.child.to_representation(item) for item in iterable
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\serializers.py", line 529, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\serializers.py", line 516, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\Saroj\Desktop\TravelCRM\myvenv\lib\site-packages\rest_framework\fields.py", line 487, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `name` on serializer `NestedSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `int` instance.
Original exception text was: 'int' object has no attribute 'name'.
For nested relations you have to define nested serializer
class DestinationSerializer(serializers.Serializer):
name = serializers.CharField()
top = serializers.BooleanField()
continent = serializers.CharField()
class PackageSerializer(serializers.ModelSerializer):
destination = DestinationSerializer()
class Meta:
model = Package
fields = ['id', 'operator','destination', 'package_name', 'duration', 'featured', 'price','price_2', 'discount',
'city', 'tour_type','new_activity', 'accommodation', 'transport', 'age_range',
'fix_departure', 'rating', 'image', 'date_created', ]

Why I am getting django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet?

Since I had same abstract model in every app model I have To avoid redundancy
I just moved my common abstract model into new app I created and called it common
Common Models.py now is
from django.db import models
LANGUAGE_CHOICES = (
('E','ENGLISH'),
('F','FRENCH'),
('S','SPANISH'),
)
class CommonInfo(models.Model):
created = models.DateTimeField("creation date", auto_now_add=True)
modified = models.DateTimeField("modification date", auto_now=True)
description = models.TextField()
class Meta:
abstract = True
then I added my common app to settings.py
And finally, in all my apps I added
from common.models import CommonInfo
from common.models import LANGUAGE_CHOICES
After running the local server this is the error I am getting in terminal (full trace)
Traceback (most recent call last): File "manage.py", line 10, in
<module>
execute_from_command_line(sys.argv) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\core\m
anagement\__init__.py", line 338, in execute_from_command_line
utility.execute() File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\core\m
anagement\__init__.py", line 312, in execute
django.setup() File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\__init
__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\apps\r
egistry.py", line 108, in populate
app_config.import_models(all_models) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\apps\c
onfig.py", line 198, in import_models
self.models_module = import_module(models_module_name) File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
__import__(name) File "C:\Users\Boris\dev\rentout\rentout\lease\models.py", line 94, in
<modu le>
class LeaseFilter(django_filters.FilterSet): File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django_filter
s\filterset.py", line 181, in __new__
filters = new_class.filters_for_model(opts.model, opts) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django_filter
s\filterset.py", line 456, in filters_for_model
cls.filter_for_reverse_field File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django_filter
s\filterset.py", line 104, in filters_for_model
filter_ = filter_for_field(field, f) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django_filter
s\filterset.py", line 461, in filter_for_field
f, lookup_type = resolve_field(f, lookup_expr) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django_filter
s\utils.py", line 104, in resolve_field
query = model_field.model._default_manager.all().query File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\manager.py", line 228, in all
return self.get_queryset() File "C:\Users\Boris\dev\rentout\rentout\lease\models.py", line 15, in
get_q ueryset
return super(NotTerminatedActiveManager, self).get_queryset().filter(is_term inated=False,is_active=True)
File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\query.py", line 679, in filter
return self._filter_or_exclude(False, *args, **kwargs) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\query.py", line 697, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs)) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\sql\query.py", line 1301, in add_q
clause, require_inner = self._add_q(where_part, self.used_aliases) File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\sql\query.py", line 1328, in _add_q
current_negated=current_negated, connector=connector, allow_joins=allow_join s) File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\sql\query.py", line 1144, in build_filter
lookups, parts, reffed_aggregate = self.solve_lookup_type(arg) File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\sql\query.py", line 1030, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_met a()) File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\sql\query.py", line 1383, in names_to_path
field_names = list(get_field_names_from_opts(opts)) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\sql\query.py", line 43, in get_field_names_from_opts
for f in opts.get_fields() File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\options.py", line 740, in get_fields
return self._get_fields(include_parents=include_parents, include_hidden=incl ude_hidden) File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\options.py", line 802, in _get_fields
all_fields = self._relation_tree File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\utils\
functional.py", line 60, in __get__
res = instance.__dict__[self.name] = self.func(instance) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\options.py", line 709, in _relation_tree
return self._populate_directed_relation_graph() File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\mod
els\options.py", line 681, in _populate_directed_relation_graph
all_models = self.apps.get_models(include_auto_created=True) File
"C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\utils\
lru_cache.py", line 101, in wrapper
result = user_function(*args, **kwds) File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\apps\r
egistry.py", line 168, in get_models
self.check_models_ready() File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\apps\r
egistry.py", line 131, in check_models_ready
raise AppRegistryNotReady("Models aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
What could be the problem? If there is a better way of grouping all common Abstract models and Choices to avoid randodancy?
UPDATE:
This is the location of the error I forgot to include
from django.db import models
from concurrency.fields import IntegerVersionField
from client.models import Tenant
from unit.models import Unit, Extra
from common.models import CommonInfo
from common.models import NOTE_STATUS_CHOICES
import django_filters
# Create your models here.
class NotTerminatedActiveManager(models.Manager):
def get_queryset(self):
return super(NotTerminatedActiveManager, self).get_queryset().filter(is_terminated=False,is_active=True)
class Lease(CommonInfo):
version = IntegerVersionField( )
amount = models.DecimalField(max_digits=7, decimal_places=2)
is_notrenewed = models.BooleanField(default=False)
unit = models.ForeignKey(Unit)
is_terminated = models.BooleanField(default=False)
not_terminated_active_objects = NotTerminatedActiveManager()
def __unicode__(self):
return u'%s %i %s %s ' % ("#", self.id,"unit", self.unit)
class LeaseConditions(CommonInfo):
version = IntegerVersionField( )
start_date = models.DateTimeField()
end_date = models.DateTimeField()
lease = models.ForeignKey(Lease)
increase = models.DecimalField(max_digits=7, decimal_places=2)
amount = models.DecimalField(max_digits=7, decimal_places=2)
is_terminated = models.BooleanField(default=False)
not_terminated_active_objects = NotTerminatedActiveManager()
def __unicode__(self):
return u'%s %i %s %s %s %s %s %s' % ("#", self.id,"first_name", self.first_name, "last_name", self.last_name, "phone", self.phone )
def clean(self):
model = self.__class__
if self.lease_id and (self.is_terminated == False) and model.objects.filter(lease=self.lease, is_active=True ).count() == 1:
raise ValidationError('!Lease has a active condition already, Terminate prior to creation of new one'.format(self.lease))
class LeaseTenant(CommonInfo):
version = IntegerVersionField( )
tenant = models.ForeignKey(Tenant)
lease = models.ForeignKey(Lease)
is_financialy_accountable = models.BooleanField(default=True)
class LeaseExtra(CommonInfo):
version = IntegerVersionField( )
extra = models.ForeignKey(Extra)
lease = models.ForeignKey(Lease)
is_included = models.BooleanField(default=True)
class LeaseDiscount(CommonInfo):
version = IntegerVersionField( )
amount = models.DecimalField(max_digits=7, decimal_places=2)
leaseconditions = models.ForeignKey(LeaseConditions)
period_date = models.DateTimeField()
class LeasePayment(CommonInfo):
version = IntegerVersionField( )
amount = models.DecimalField(max_digits=7, decimal_places=2)
lease = models.ForeignKey(Lease)
period_payed_for = models.DateTimeField()
payment_date = models.DateTimeField()
class Note(CommonInfo):
version = IntegerVersionField( )
title = models.CharField(max_length=200)
contact = models.ForeignKey(Lease)
followup_date = models.DateTimeField(null=True, blank=True)
status = models.CharField(max_length=1, default='P',
choices=NOTE_STATUS_CHOICES)
#widgets = {
#Use localization and bootstrap 3
#'datetime': DateTimeWidget(attrs={'id':"id_followup_date"}, usel10n = True, bootstrap_version=3)}
def __unicode__(self):
return u'%s %s %s %s %s %i %s %s %s %s %s %s %s %s' % ("Status:", self.status, "Follow Date:", self.followup_date, "Note #:", self.id, "Published:", self.creation_time, "Author:",self.author,"/Title:" , self.title,"/Body:" , self.body )
class LeaseFilter(django_filters.FilterSet):
class Meta:
model = Lease
fields = ['is_notrenewed', 'unit',
'is_terminated']
#provider = django_filters.ModelChoiceFilter(queryset=Provider.objects.all(),
#name = django_filters.ModelChoiceFilter(queryset=Lease.objects.all().order_by('name'))
I don't think the LeaseFilter class belongs in your models. It looks as if it is trying to do queries when the class is loaded. Since the models haven't loaded yet, this causes the error. Try moving the class somewhere else, for example your views.py.

Unittesting Django CreateView with mock library

I'm trying to test my CreateView by posting some data and mocking models' save() method.
class BaseViewTest(TestCase):
def setUp(self):
self.user = UserFactory()
self.factory = RequestFactory()
class MuayeneCreateViewTest(BaseViewTest):
def test_get(self):
request = self.factory.get(reverse('muayene:create'))
request.user = self.user
response = MuayeneCreateView.as_view()(request)
self.assertEqual(response.status_code, 200)
self.assertTrue('form' in response.context_data)
self.assertTrue('muayene/muayene_form.html' in response.template_name)
#patch('muayene.models.Muayene.save', MagicMock(name="save"))
def test_post(self):
hasta = HastaFactory()
ilac1 = IlacFactory()
ilac2 = IlacFactory()
data = {
'hasta': hasta.id,
'tarih': str(datetime.date.today()),
'yakinma': 'Kusma',
'kullandigi_ilaclar': [ilac1.id, ilac2.id],
'öntani_tani': 'Öntanı ve tanı',
'öneri_görüsler': 'Öneri ve Görüşler',
'özel_notlar': 'Özel notlar'
}
request = self.factory.post(reverse('muayene:create'), data)
request.user = self.user
response = MuayeneCreateView.as_view()(request)
self.assertEqual(response.status_code, 302)
self.assertTrue(Muayene.save.called)
self.assertEqual(Muayene.save.call_count, 1)
Here is MuayeneCreateView:
class MuayeneCreateView(LoginRequiredMixin, CreateView):
login_url = '/login/'
model = Muayene
form_class = MuayeneCreateForm
and traceback:
ERROR: test_post (tests.test_muayene.MuayeneCreateViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib64/python3.5/unittest/mock.py", line 1157, in patched
return func(*args, **keywargs)
File "/home/egegunes/Dropbox/Programs/hastatakip/tests/test_muayene.py", line 153, in test_post
response = MuayeneCreateView.as_view()(request)
File "/usr/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/django/contrib/auth/mixins.py", line 56, in dispatch
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/django/views/generic/edit.py", line 256, in post
return super(BaseCreateView, self).post(request, *args, **kwargs)
File "/usr/lib/python3.5/site-packages/django/views/generic/edit.py", line 222, in post
return self.form_valid(form)
File "/usr/lib/python3.5/site-packages/django/views/generic/edit.py", line 201, in form_valid
self.object = form.save()
File "/usr/lib/python3.5/site-packages/django/forms/models.py", line 452, in save
self._save_m2m()
File "/usr/lib/python3.5/site-packages/django/forms/models.py", line 434, in _save_m2m
f.save_form_data(self.instance, cleaned_data[f.name])
File "/usr/lib/python3.5/site-packages/django/db/models/fields/related.py", line 1618, in save_form_data
setattr(instance, self.attname, data)
File "/usr/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 480, in __set__
manager = self.__get__(instance)
File "/usr/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 468, in __get__
return self.related_manager_cls(instance)
File "/usr/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 751, in __init__
(instance, self.source_field_name))
ValueError: "<Muayene: ID: None - 2016-07-31 - Bob Baz>" needs to have a value for field "muayene" before this many-to-many relationship can be used.
I couldn't figure out what causes this error. Muayene instance is used by some other models but IMO this error must not show up unless I try to create one of those models with this instance.
Edit
Muayene model:
class Muayene(models.Model):
hasta = models.ForeignKey(
'hasta.Hasta',
on_delete=models.CASCADE
)
tarih = models.DateField(
default = timezone.now
)
yakinma = models.TextField(
max_length = 255,
blank = True,
null = True
)
kullandigi_ilaclar = models.ManyToManyField(
Ilac,
blank = True
)
baki = models.TextField(
max_length = 255,
blank = True,
null = True
)
öntani_tani = models.TextField(
max_length = 255,
blank = True,
null = True
)
öneri_görüsler = models.TextField(
max_length = 255,
blank = True,
null = True
)
özel_notlar = models.TextField(
max_length = 255,
blank = True,
null = True
)
def __str__(self):
tarih = str(self.tarih)
hasta = str(self.hasta.ad + " " + self.hasta.soyad)
pk = str(self.pk)
return "ID: " + pk + " - " + tarih + " - " + hasta
def get_absolute_url(self):
return reverse('muayene:detail', kwargs={'pk':self.pk})
def was_today(self):
today = datetime.date.today()
if today - datetime.timedelta(days=1) <= self.tarih <= today:
return True
else:
return False
Models in relation with Muayene:
class Recete(models.Model):
hasta = models.ForeignKey(
'hasta.Hasta',
on_delete=models.CASCADE
)
muayene = models.ForeignKey(
'muayene.Muayene',
on_delete=models.CASCADE,
)
tarih = models.DateField(
default = timezone.now
)
ilaclar = models.ManyToManyField(Ilac)
def __str__(self):
return str(self.tarih)
def get_absolute_url(self):
return reverse('muayene:recete-detail', kwargs={'pk':self.pk})
class Rapor(models.Model):
hasta = models.ForeignKey(
'hasta.Hasta',
on_delete=models.CASCADE
)
muayene = models.ForeignKey(
'muayene.Muayene',
on_delete=models.CASCADE
)
tarih = models.DateField(
default = timezone.now
)
tani = models.CharField(
blank = True,
null = True,
max_length = 255
)
gun = models.PositiveSmallIntegerField(
default = 1
)
def __str__(self):
return str(self.hasta)
def get_absolute_url(self):
return reverse('muayene:rapor-detail', kwargs={'pk':self.pk})
class LaboratuvarIstek(models.Model):
hasta = models.ForeignKey(
'hasta.Hasta',
on_delete=models.CASCADE
)
muayene = models.ForeignKey(
'muayene.Muayene',
on_delete=models.CASCADE,
)
tarih = models.DateField(
default = timezone.now
)
istekler = models.ManyToManyField(Laboratuvar)
def __str__(self):
return str(self.hasta)
def get_absolute_url(self):
return reverse('muayene:lab-detail', kwargs={'pk':self.pk})
You can actually see failing reason in your traceback:
File "/usr/lib/python3.5/site-packages/django/forms/models.py", line 452, in save
self._save_m2m()
That is because your view doesn't call model's save method directly. Instead it gets form that is used for model (or creates one with factory) and calls form's save method. You can check this method at django.forms.models.BaseModelForm.save. So if you really want to count calls on model instance and don't wanna fail test, you shoud mock django.forms.models.BaseModelForm._save_m2m too, because it gets called in form's save method.

ManyToMany relation with a through model using factory_boy?

I'm facing the problem when creating the many to many relation with through model using factory. I followed this link factory recipies.
I'm getting the TypeError: 'datetime.date' object is not callable this error. Help me to find the solution.
I got an another error:
File "/local/lib/python2.7/site-packages/factory/base.py", line 492, in _generate
obj = cls._prepare(create, **attrs)
File "/local/lib/python2.7/site-packages/factory/base.py", line 467, in _prepare
return cls._create(model_class, *args, **kwargs)
File "/local/lib/python2.7/site-packages/factory/django.py", line 174, in _create
return manager.create(*args, **kwargs)
File "/local/lib/python2.7/site-packages/django/db/models/manager.py", line 127, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/local/lib/python2.7/site-packages/django/db/models/query.py", line 346, in create
obj = self.model(**kwargs)
File "/local/lib/python2.7/site-packages/django/db/models/base.py", line 480, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'a1' is an invalid keyword argument for this function
models.py
class TimeStampModel(models.Model):
start_date = models.DateField(_('Start Date'))
end_date = models.DateField(_('End Date'))
class Meta:
abstract = True
class User(models.Model):
name = models.CharField()
class Aclass(models.Model):
name = models.CharField()
user = models.ForeignKey(User)
report = models.ManyToManyField('self', through='Bcalss')
class Bcalss(TimeStampModel):
a1 = models.ForeignKey(Aclass)
b1 = models.ForeignKey(Aclass)
factories.py
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.User
name = "John Doe"
class AclassFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Aclass
user = factory.SubFactory(UserFactory)
name = "Admins"
class BclassFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Bclass
a1 = factory.SubFactory(AclassFactory)
b1 = factory.SubFactory(AclassFactory)
start_date = fuzzy.FuzzyDate(timezone.localtime(timezone.now())).date(), timezone.localtime(timezone.now())).date() + timedelta(days=2))
end_date = fuzzy.FuzzyDate(timezone.localtime(timezone.now())).date(), timezone.localtime(timezone.now())).date() + timedelta(days=6))
class AclassWithBclassFactory(AclassFactory):
reports = factory.RelatedFactory(BclassFactory, 'a1')
tests.py
class A1classModelTestCase(TestCase):
def test_a1class_create(self):
a1 = factories.AclassWithBclassFactory.create()
In this line:
start_date = factory.LazyAttribute(datetime.today)
You need to actually call the function with ():
start_date = factory.LazyAttribute(datetime.today())

Django Error: __init__() takes exactly 2 arguments (3 given)

Anyone can find what is causing the error in my code? I already searched, but didn't find an answer. I think the problem is with the function objects.get(param), but I'm not sure.
What I wanted to do with my code was to retrieve the objects Genre, Country, Language and Directors if they were already added to the database.
Here's the code:
Models.py
from django.db import models
from numpy import unique
class Director(models.Model):
director = models.CharField(max_length=500, unique=True)
def __unicode__(self):
return self.director
def __init__(self, director):
super(Director, self).__init__()
self.director = director
class Language(models.Model):
language = models.CharField(max_length=500, unique=True)
def __unicode__(self):
return self.language
def __init__(self, language):
super(Language, self).__init__()
self.language = language
class Genre(models.Model):
genre = models.CharField(max_length=500, unique=True)
def __unicode__(self):
return self.genre
def __init__(self, genre):
super(Genre, self).__init__()
self.genre = genre
class Country(models.Model):
country = models.CharField(max_length=500, unique=True)
def __unicode__(self):
return self.country
def __init__(self, country):
super(Country, self).__init__()
self.country = country
class Movie(models.Model):
id_movie = models.CharField(max_length=200, unique=True)
rating = models.CharField(max_length=200)
votes = models.CharField(max_length=200)
year = models.CharField(max_length=10)
genre = models.ManyToManyField(Genre)
country = models.ManyToManyField(Country)
language = models.ManyToManyField(Language)
directors = models.ManyToManyField(Director)
def __init__(self, id_movie, rating, votes, year):
super(Movie, self).__init__()
self.id_movie = id_movie
self.rating = rating
self.votes = votes
self.year = year
def __unicode__(self):
return self.id_movie
crawler.py
from movie_info.models import Movie, Genre, Director, Language, Country
def get_movie_info(codigo_do_filme):
import imdb
ia = imdb.IMDb()
movie = ia.get_movie(codigo_do_filme)
return {'titulo': movie['title'], 'rating': movie['rating'], 'votes': movie['votes'], 'ano': movie['year'], 'genero': movie['genre'][0], 'pais': movie['countries'][0], 'idioma': movie['lang'][0], 'directors': movie['director']}
def read_sheet(file_name, fieldnames=None, delimiter=",", quotechar="\n"):
from csv import DictReader
reader = DictReader(open(file_name,'rb'), fieldnames = fieldnames, delimiter = delimiter, quotechar=quotechar)
return reader
def fill_db_movie_info(the_sheet_file):
file_csv = read_sheet(the_sheet_file)
for movie in file_csv:
id_filme = movie['id_move']
if not Movie.objects.filter(id_movie=id_filme).exists():
info = get_movie_info(id_filme)
rating_imdb = info['rating']
movie_votes = info['votes']
movie_year = info['ano']
movie_genre = info['genero']
movie_country = info['pais']
movie_lang = info['idioma']
movie_directors = info['directors']
addToDB = Movie(id_filme, rating_imdb, movie_votes, movie_year)
addToDB.save()
if not Genre.objects.filter(genre=movie_genre).exists():
genreToDB = Genre(movie_genre)
genreToDB.save()
addToDB.genre.add(genreToDB)
else:
addToDB.genre.add(Genre.objects.get(genre=movie_genre))
if not Country.objects.filter(country=movie_country).exists():
countryToDB = Country(movie_country)
countryToDB.save()
addToDB.country.add(countryToDB)
else:
addToDB.country.add(Country.objects.get(country=movie_country))
if not Language.objects.filter(language=movie_lang).exists():
langToDB = Language(movie_lang)
langToDB.save()
addToDB.language.add(langToDB)
else:
addToDB.language.add(Language.objects.get(language=movie_lang))
for m_director in movie_directors:
if not Director.objects.filter(director=m_director['name']).exists():
directorsToDB = Director(m_director['name'])
directorsToDB.save()
addToDB.directors.add(directorsToDB)
else:
addToDB.directors.add(Director.objects.get(director=m_director['name']))
print "salvou: " + id_filme, rating_imdb, movie_votes, movie_year, movie_genre, movie_country, movie_lang, movie_directors[0]
The Traceback:
pydev debugger: starting (pid: 1424)
Traceback (most recent call last):
File "/Applications/eclipse/plugins/org.python.pydev_3.5.0.201405201709/pysrc/pydevd.py", line 1845, in <module>
debugger.run(setup['file'], None, None)
File "/Applications/eclipse/plugins/org.python.pydev_3.5.0.201405201709/pysrc/pydevd.py", line 1373, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Users/rubenspessoa/Documents/Workspace/LearningDjango/main.py", line 7, in <module>
fill_db_movie_info('/Users/rubenspessoa/Documents/Workspace/DATASET/test_subdataset.csv')
File "/Users/rubenspessoa/Documents/Workspace/LearningDjango/crawler.py", line 49, in fill_db_movie_info
addToDB.country.add(Country.objects.get(country=movie_country))
File "/Library/Python/2.7/site-packages/django/db/models/manager.py", line 151, in get
return self.get_queryset().get(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 304, in get
num = len(clone)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 77, in __len__
self._fetch_all()
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 857, in _fetch_all
self._result_cache = list(self.iterator())
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 230, in iterator
obj = model(*row_data)
TypeError: __init__() takes exactly 2 arguments (3 given)
You have defined __init__ methods for all your models. You should not do that.