Django TypeError - python

I get an error with model like this:
class Project(models.Model): # Should Rename to Project Name
project_name = models.CharField(max_length=50)
frequency = models.PositiveIntegerField(blank=True)
related_tests = models.ManyToManyField(TestType)
creation_date = models.DateField()
def __init__(self, *args, **kwargs):
super().__init__(self, *args, **kwargs)
self.creation_date = datetime.date.today()
Error: int() argument must be a string, a bytes-like object or a number, not 'Project'
When I comment out,
creation_date = models.DateField()
def __init__(self, *args, **kwargs):
super().__init__(self, *args, **kwargs)
self.creation_date = datetime.date.today()
...the code works.
My question is, what is prompting the error?

You don't need to pass self to __init__ with super:
super().__init__(*args, **kwargs)
Or in python 2, you should do:
super(Project, self).__init__(*args, **kwargs)

Related

override save and clean method in django

hello i have StoreCheckout model and i override save and clean method but conditions in override methods not work.
class StoreCheckout(models.Model):
store = models.ForeignKey(
to=Store,
on_delete=models.CASCADE,
limit_choices_to={
'is_confirm': True
},
)
pay_date = models.DateTimeField()
amount = models.PositiveBigIntegerField()
bank_number = models.PositiveBigIntegerField(validators=[bank_number_validate])
def __str__(self):
return self.store.name
def save(self, *args, **kwargs):
if not self.bank_number:
self.bank_number = self.store.bank_number
if not self.pay_date:
self.pay_date = datetime.now()
super(StoreCheckout, self).save(*args, **kwargs)
def clean(self, *args, **kwargs):
if not settings.MIN_CHECKOUT <= self.store.wallet <= settings.MAX_CHECKOUT:
raise ValidationError(
f'amount of your store must between {settings.MIN_CHECKOUT} and {settings.MAX_CHECKOUT} toman'
)
super(StoreCheckout, self).save(*args, **kwargs)

Django-import-export - How to pass user information to ForeignKeyWidget?

I need to somehow pass the user information to ForeignKeyWidget class from resource class, where I create ForeignKey object:
class CompanyWidget(ForeignKeyWidget):
def clean(self, value, row=None, *args, **kwargs):
print(self.user, file=sys.stderr)
if not value:
return None
else:
obj, _ = Company.objects.get_or_create(
name=value,
created_by='I NEED USER INFORMATION HERE SOMEHOW',
)
return obj
What is the best way to do this?
I've tried to solve this on my own and got pretty close, but could not fit the last piece of the puzzle. You override __init__ class in resource and get user information there. Then, I could not figure out how to pass this self.user information into the class variable company.
Here is the code:
class ContactResource(resources.ModelResource):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(ContactResource, self).__init__(*args, **kwargs)
company = fields.Field(
column_name='company',
attribute='company',
widget=CompanyWidget(model=Company, field='name', user='I NEED TO PASS USER HERE FROM __INIT__'))
def after_import_instance(self, instance, new, **kwargs):
instance.created_by = kwargs['user']
If I somehow manage to pass user information in **kwargs of company variable, then I can use it downstream by overriding ForeignKeyWidget's __init__ class:
class CompanyWidget(ForeignKeyWidget):
def __init__(self, model, field='pk', *args, **kwargs):
self.model = model
self.field = field
self.user = kwargs.pop('user', None)
super(CompanyWidget, self).__init__(model, *args, **kwargs)
def clean(self, value, row=None, *args, **kwargs):
print(self.user, file=sys.stderr)
if not value:
return None
else:
obj, _ = Company.objects.get_or_create(
name=value,
created_by=self.user,
)
return obj
Any help would be appreciated, it took me forever to get here and I feel I am really close. Thank you in advance.
It turns out it is easier to implement this without using ForeignKeyWidget at all.
If you have multiple foreign keys that are not unique but have the same name (in my case, same company name created by different users), this is how you could solve the problem:
class ContactResource(resources.ModelResource):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(ContactResource, self).__init__(*args, **kwargs)
company = fields.Field(column_name='company')
class Meta:
model = Contact
skip_unchanged = True
report_skipped = True
exclude =('is_active', 'created_by')
export_order = ('id','first_name','last_name','email','phone','address','description','company','created_on','website','job_title','birthday')
def after_import_instance(self, instance, new, **kwargs):
instance.created_by = self.user # kwargs['user']
def import_field(self, field, obj, data):
field_name = self.get_field_name(field)
method = getattr(self, 'clean_%s' % field_name, None)
if method is not None:
obj = method(field, obj, data)
super(ContactResource, self).import_field(field, obj, data)
def clean_company(self, field, obj, data):
name = data[field.column_name]
company, created = Company.objects.get_or_create(name=name, created_by=self.user)
obj.company = company
return obj

ModelForm in Django

ModelForm:
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(ChapterCreateForm, self).__init__(*args, **kwargs)
Not working
I wanna add self.field other. But it not working.
This is my code:
class ChapterCreateForm(ModelForm):
class Meta:
model = Chapter
exclude = ('user', 'book',)
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(ChapterCreateForm, self).__init__(*args, **kwargs)
def clean_title(self):
title = self.cleaned_data['title']
if Chapter.objects.filter(user=self.user, title=title).exists():
raise forms.ValidationError('THIS CHAPTER ALREADY WRITTEN')
return title
But this form it's working:
class BookCreateForm(ModelForm):
class Meta:
model = Book
exclude = ('user',)
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(BookCreateForm, self).__init__(*args, **kwargs)
def clean_title(self):
title = self.cleaned_data['title']
if Book.objects.filter(title=title).exists():
if Book.objects.filter(user=self.user, title=title).exists():
raise forms.ValidationError('YOU WROTE THIS BOOK ')
raise forms.ValidationError('THIS BOOK ALREADY WRITTEN')
return title
Please help me. Thanks so much
You need to pass user in the form kwargs by overriding get_form_kwargs in the class UserCreateChapterView as below:
class UserCreateChapterView(UserPassesTestMixin, CreateView):
...
...
def get_form_kwargs(self):
kwargs = super(UserCreateChapterView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
Now you can use kwargs.pop('user') in the __init__ method of ChapterCreateForm and it should work.
Hope it helps!

django application with postgresql error value too long for type character varying(1)

I have a problem with django app and POSTGRESQL database with the slug field.
Error:
value too long for type character varying(1)
I test my app with sqlite database and everything works fine, but my app does not work in postgresql database. Any ideas why this is the case?
Test 1:
class MyModel(models.Model):
name = models.CharField(max_length=254)
slug_name = models.SlugField(max_length=254)
def save(self, *args, **kwargs):
self.slug_name = slugify(self.name)
super(MyModel, self).save(*args, **kwargs)
Test 2:
class MyModel(models.Model):
name = models.TextField(max_length=500)
slug_name = models.SlugField(max_length=500)
def save(self, *args, **kwargs):
self.slug_name = slugify(self.name)
super(MyModel, self).save(*args, **kwargs)
Test 3:
class MyModel(models.Model):
name = models.TextField()
slug_name = models.SlugField()
def save(self, *args, **kwargs):
self.slug_name = slugify(self.name)
super(MyModel, self).save(*args, **kwargs)
You're trying to insert a value with more that one character into a field specified as character varying(1). SQLite3 will allow this (see https://sqlite.org/datatype3.html) but PostgreSQL will give an error - i.e., it enforces that you have specified the maximum length as 1.

Queryset in __init__ Form Django

class PaymentSelectForm(forms.Form):
date_from = forms.DateField()
date_to = forms.DateField()
website = ModelChoiceField()
paymentmethod = forms.ChoiceField(choices=PAYCODE_CHOICES)
def __init__(self, *args, **kwargs):
super(PaymentSelectForm, self).__init__(*args, **kwargs)
applyClassConfig2FormControl(self)
self.fields['website'].queryset=Website.objects.all()
I have errors: TypeError: __init__() missing 1 required positional argument: 'queryset'. How can I use Queryset in __init__ Form?
Unless there is some information you are currently hiding, you better declare the queryset in the declaration of the ModelChoiceField:
class PaymentSelectForm(forms.Form):
date_from = forms.DateField()
date_to = forms.DateField()
website = ModelChoiceField(queryset=Website.objects.all())
paymentmethod = forms.ChoiceField(choices=PAYCODE_CHOICES)
def __init__(self, *args, **kwargs):
super(PaymentSelectForm, self).__init__(*args, **kwargs)
applyClassConfig2FormControl(self)
In case the queryset is dynamic (this is not the case here), you can set it to None initially, and then overwrite it in the __init__ function:
class PaymentSelectForm(forms.Form):
date_from = forms.DateField()
date_to = forms.DateField()
website = ModelChoiceField(queryset=None)
paymentmethod = forms.ChoiceField(choices=PAYCODE_CHOICES)
def __init__(self, *args, **kwargs):
super(PaymentSelectForm, self).__init__(*args, **kwargs)
applyClassConfig2FormControl(self)
self.fields['website'].queryset=Website.objects.all()
But this is usually the case if for instance the queryset depends on parameters that are passed to the form, or it depends on other tables (and it can not be written into an SQL query elegantly).
Use widget.choices
def __init__(self, *args, **kwargs):
super(PaymentSelectForm, self).__init__(*args, **kwargs)
applyClassConfig2FormControl(self)
self.fields['website'].widget.choices=(
(choice.pk, choice) for choice in Website.objects.all()
)

Categories