attribute error in django. django.db.models has no attribute - django

I am trying to write the code so that a user in the system can view complaint registered by others on this page but not their own complaints. This is the code, but I don't understand what's wrong:
views.py:
class OtherPeoplesComplaints(TemplateView):
model = Complaint
form_class = ComplaintForm
template_name = 'userComplaints.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context["complaints"] = models.Complaint.objects.exclude(
profile__user = self.request.user
)
models.py:
class Complaint(models.Model):
user = models.ForeignKey(User, on_delete= models.CASCADE, null = True, blank=True)
id = models.AutoField(blank=False, primary_key=True)
reportnumber = models.CharField(max_length=500 ,null = True, blank= False)
eventdate = models.DateField(null=True, blank=False)
event_type = models.CharField(max_length=300, null=True, blank=True)
device_problem = models.CharField(max_length=300, null=True, blank=True)
manufacturer = models.CharField(max_length=300, null=True, blank=True)
product_code = models.CharField(max_length=300, null=True, blank=True)
brand_name = models.CharField(max_length = 300, null=True, blank=True)
exemption = models.CharField(max_length=300, null=True, blank=True)
patient_problem = models.CharField(max_length=500, null=True, blank=True)
event_text = models.TextField(null=True, blank= True)
document = models.FileField(upload_to='static/documents', blank=True, null=True)
def __str__(self):
return self.reportnumber
forms.py:
class DateInput(forms.DateInput):
input_type = 'date'
class ComplaintForm(ModelForm):
class Meta:
model = Complaint
fields = '__all__'
widgets = {
'reportnumber': forms.TextInput(attrs={'placeholder': 'Report number'}),
'event_type': forms.TextInput(attrs={'placeholder': 'Event type'}),
'eventdate': DateInput(),
'device_problem': forms.TextInput(attrs={'placeholder': 'Device Problem'}),
'event_text': forms.Textarea(attrs={'style': 'height: 130px;width:760px'}),
'manufacturer': forms.TextInput(attrs={'placeholder': 'Enter Manufacturer Name'}),
'product_code': forms.TextInput(attrs={'placeholder': 'Enter Product Code'}),
'brand_name': forms.TextInput(attrs={'placeholder': 'Enter Brand Name'}),
'exemption': forms.TextInput(attrs={'placeholder': 'Enter Exemption'}),
'patient_problem': forms.TextInput(attrs={'placeholder': 'Enter Patient Problem'}),
}
def clean(self):
cleaned_data = super(ComplaintForm, self).clean()
reportnumber = cleaned_data.get('reportnumber')
event_text = cleaned_data.get('event_text')
if not reportnumber and not event_text:
raise forms.ValidationError('You have to write something!')
return cleaned_data

In this view
class OtherPeoplesComplaints(TemplateView):
model = Complaint
form_class = ComplaintForm
template_name = 'userComplaints.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context["complaints"] = models.Complaint.objects.exclude(
profile__user = self.request.user
)
you are using this query :
context["complaints"] = models.Complaint.objects.exclude(profile__user = self.request.user)
change it to :
context["complaints"] = self.model.objects.exclude(user = self.request.user)
Explanation :
Your model is Complaint which you can access using self.model as you have defined the class variable here :
class OtherPeoplesComplaints(TemplateView):
model = Complaint
and
You want to access complaint of other users except your own, so this update in your query :
exclude(user = self.request.user)

Related

Django-Shapeshifiter problems

I quite new to django and I'm working in a simple project for the University. I'm trying to use the django-shapeshifter, but just by entering like in the example they provide, I get a syntax error I have one main table connected to tow tables with manytomany relations and would like to work with a single view to deal with the forms.
The models:
class PreciosUnitarios(models.Model):
redimiento = models.ForeignKey(Rendimientos, on_delete=models.CASCADE)
mano_obra = models.ManyToManyField(ManoObra, through='PuManoObra')
material_id = models.ManyToManyField(Materiales, through='Pu_Material')
valor_mo = models.FloatField(
validators=[validate_decimals], blank=True, null=True)
valor_material = models.FloatField(
validators=[validate_decimals], blank=True, null=True)
def __str__(self) -> str:
return self.redimiento.nombre
def get_total(self):
return self.valor_mo+self.valor_material
def get_absolute_url(self):
return reverse('pu_detail', kwargs={'pk': self.pk})
def save(self, *args, **kwargs):
if self.id:
pk = self.id
v = Variables.objects.get(pk=2)
rm = self.redimiento.unidades_jornal
jc = ManoObra.objects.get(cargo='Jefe de Cuadrilla')
pu_m = Pu_Material.objects.filter(pu_id=pk)
pu_mo = PuManoObra.objects.filter(pu_id=pk)
tm = pu_m.aggregate(Sum('subtotal'))['subtotal__sum']
tmo = pu_mo.aggregate(Sum('mo_subtotal'))['mo_subtotal__sum']
tmo = (tmo + (((jc.salario*8)/208) * 0.10))/rm
total_herramientas = tmo * v.herramientas
total_seguridad = tmo * v.seguridad
subtotal = tm+tmo+total_herramientas+total_seguridad
total = subtotal / (1 - v.gastos_admin)
total = total/(1-v.utilidad)
total = total*v.iva
self.valor_mo = total * \
(tmo/(subtotal))
self.valor_material = total * \
(tm/(subtotal))
super().save(*args, **kwargs)
else:
super().save(*args, **kwargs)
class PuManoObra(models.Model):
manoObra_id = models.ForeignKey(ManoObra, on_delete=models.CASCADE)
pu_id = models.ForeignKey(
PreciosUnitarios, on_delete=models.CASCADE, null=True, blank=True)
valor_jornal = models.FloatField(
validators=[validate_decimals], null=True, blank=True)
mo_subtotal = models.FloatField(
validators=[validate_decimals], null=True, blank=True)
ctd = models.PositiveIntegerField(default=1)
def __str__(self) -> str:
return self.pu_id.redimiento.nombre + ", "+self.manoObra_id.cargo
def save(self, *args, **kwargs):
vj = self.manoObra_id.salario/26
self.valor_jornal = vj
self.mo_subtotal = self.ctd*vj
super().save(*args, **kwargs)
class Pu_Material(models.Model):
material_id = models.ForeignKey(Materiales, on_delete=models.CASCADE)
pu_id = models.ForeignKey(
PreciosUnitarios, on_delete=models.CASCADE, null=True, blank=True)
cantidad = models.PositiveIntegerField(default=1)
subtotal = models.FloatField(
validators=[validate_decimals], null=True, blank=True)
class Meta():
unique_together = [['material_id', 'pu_id']]
def __str__(self) -> str:
return self.pu_id.redimiento.nombre + ", Material: "+self.material_id.material_nombre
def save(self, *args, **kwargs):
self.subtotal = self.material_id.precio*self.cantidad
super().save(*args, **kwargs)
my forms:
class PrecioUnitarioForm(forms.ModelForm):
class Meta():
model = PreciosUnitarios
fields = ('redimiento',
# 'mano_obra',
# 'material_id',
# 'valor_mo',
# 'valor_material'
)
labels = {
'redimiento': 'Selecionar Rendimiento',
'mano_obra': 'Selecionar Mano de Obra',
'material_id': '',
'valor_mo': '',
'valor_material': '',
}
widgets = {
'redimiento': forms.Select(attrs={'class': 'form-control'}),
'mano_obra': forms.SelectMultiple(attrs={'class': 'form-control'}),
'material_id': forms.SelectMultiple(attrs={'class': 'form-control'}),
'valor_mo': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Precio del Material'}),
'valor_material': forms.TextInput(attrs={'class': 'form-control'}),
}
class PuMaterialForm(forms.ModelForm):
class Meta():
model = Pu_Material
fields = (
'material_id', 'pu_id', 'cantidad'
)
labels = {
'material_id': 'Material', 'pu_id': 'Preciounitario', 'cantidad': ''
}
widgets = {
'material_id': forms.Select(attrs={'class': 'form-control'}),
'pu_id': forms.Select(attrs={'class': 'form-control'}),
'cantidad': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Cantidad'})
}
class PuManoObraForm(forms.ModelForm):
class Meta():
model = PuManoObra
fields = (
'manoObra_id', 'pu_id', 'ctd'
)
labels = {'manoObra_id': 'Mano de Obra',
'pu_id': 'Precio Unitario',
'ctd': ''
}
widgets = {
'manoObra_id': forms.Select(attrs={'class': 'form-control'}),
'pu_id': forms.Select(attrs={'class': 'form-control'}),
'ctd': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Cantidad'})
}
the shapeshift code:
class PrecioUnitarioFormView(MultiModelFormView):
form_classes = ('PrecioUnitarioForm', 'PuMaterialForm', 'PuManoObraForm')
template_name = 'cotizacion/preciosunitarios.html'
success_url = 'cotizacion/pu_detail.html'
success_message = ''
def get_instances(self):
instances = {
'preciounitariofomr': self.request.preciosunitarios,
'pumaterialform': Pu_Material.objects.filter(
user=self.request.preciosunitarios).first(),
'pumanoobraform': PuManoObra.objects.filter(
user=self.request.preciosunitarios).first()
}
return instances
the error says that "object has no attribute name".
Anyone can help?

RelatedObjectDoesNotExist at /updateprofile User has no profile

i have one model userprofile which is connected to User by onetoone relationship. i am trying to create combined form for both user and userprofile form but it is showing onetoonedescripter has no attribute _meta.
views.py
'''
def UpdateProfile(request):
if request.method =='POST':
EUF_form = EditUserForm(request.POST, instance=request.user )
EPF_form = EditProfileForm(request.POST, instance=request.user.Profile )
if EUF_form.is_valid() and EPF_form.i_valid():
EUF_form.save()
EPF_form.save()
return HttpResponse("Profile updated succesfully.")
return render(request, 'profile_page.html')
else:
EUF_form = EditUserForm(instance=request.user)
EPF_form = EditProfileForm(instance=request.user.profile)
return render(request, 'edit_profile.html', {'EUF_form':EUF_form, 'EPF_form':EPF_form})
'''
models.py
'''
class Profile(models.Model):
user = models.OneToOneField(User, on_delete= models.CASCADE)
mobile = models.CharField(max_length=20, blank=True)
bio = models.CharField(max_length=300, default='')
avatar = models.ImageField(upload_to='avatars', blank=True)
birthday = models.DateField(blank=True, default='1990-12-01')
website = models.CharField(blank=True, max_length=256)
gender = models.CharField(blank=True, max_length=20, choices=[('M','Male'), ('F','Female'),('O','Other')])
def __str__(self):
return self.user.username
'''
forms.py
'''
class EditUserForm(ModelForm):
first_name = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'text','name': 'first_name'}),
label="First Name")
last_name = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'text','name': 'last_name'}),
label="Last Name")
username = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'text','name': 'username'}),
label="Username")
email = forms.EmailField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'text','name': 'email'}),
label="Email")
class Meta:
model = User
fields = ['first_name','last_name','username','email']
class EditProfileForm(ModelForm):
mobile = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control','type':'tel','name': 'mobile'}),
label="Phone number")
bio = forms.CharField(widget=forms.Textarea,
label="Bio")
birthday = forms.DateField(widget=forms.DateInput(
attrs={'class': 'form-control','type':'date','name': 'birthday'}),
label="Username")
website = forms.URLField(widget=forms.URLInput(
attrs={'class': 'form-control','type':'url','name': 'website'}),
label="website")
gender = forms.ChoiceField(choices=[('M','Male'), ('F','Female'),('O','Other')],
widget=forms.Select ,
label="gender")
class Meta:
model = Profile
fields = ['mobile','bio','birthday','website','gender']
'''

Saving formset when a compulsory field was not supplied?

I get an error "NOT NULL constraint failed" when I try to save a formset in an update view and the formset has had new forms added. I think the reason is that the database has a required field (journal_entry) that isn't part of the Formset ModelForm. So when the formset is attempted to be saved lineitem_formset.save() I get the error.
How can I add this required field value before saving the formset?
View.py
#login_required
def entries_update(request, pk):
journal_entry = get_object_or_404(JournalEntry, pk=pk)
journal_entry.date = journal_entry.date.strftime('%Y-%m-%d') #Convert date format to be suitable for Datepicker input.
journal_entry_form = JournalEntryForm(instance=journal_entry)
LineItemFormSet = modelformset_factory(LineItem, fields=('ledger','description','project','cr','dr'), extra=2)
line_items = LineItem.objects.filter(journal_entry=journal_entry)
lineitem_formset = LineItemFormSet(queryset=line_items)
if request.method == 'POST':
lineitem_formset = LineItemFormSet(request.POST)
journal_entry_form = JournalEntryForm(request.POST, instance=journal_entry)
if lineitem_formset.is_valid() and journal_entry_form.is_valid:
lineitem_formset.save() <-- ERROR HAPPENS HERE
journal_entry_form.save()
messages.success(request, "Journal entry successfully updated.")
return HttpResponseRedirect(reverse('journal:entries_show_detail', kwargs={'pk': journal_entry.id}) )
Models.py
class JournalEntry(models.Model):
# User needs to be set back to compulsory !!!
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True)
date = models.DateField(null=False, blank=False)
TYPE = (
('BP', 'Bank Payment'),
('YE', 'Year End'),
('JE', 'Journal Entry')
)
type = models.CharField(
max_length=2,
choices=TYPE,
blank=True,
default='0'
)
description = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
if self.description:
return self.description
else:
return 'Journal Entry' + str(self.id)
class Meta(object):
ordering = ['id']
verbose_name_plural = 'Journal entries'
class LineItem(models.Model):
journal_entry = models.ForeignKey(JournalEntry, on_delete=models.CASCADE) <--- This is the field that needs to be set.
ledger = models.ForeignKey(Ledger, on_delete=models.PROTECT)
description = models.CharField(max_length=255, null=True, blank=True)
project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True)
cr = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)
dr = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)
STATUS = (
('0', 'Not reconciled'),
('1', 'Draft'),
)
status = models.CharField(
max_length=1,
choices=STATUS,
default='0'
)
reconciliation_date = models.DateField(null=True, blank=True)
#def __str__(self):
# return self.description
class Meta(object):
ordering = ['id']
forms.py
class JournalEntryForm(ModelForm):
def clean_date(self):
data = self.cleaned_data['date']
#Check date is not more than 30d future
if data > (datetime.date.today() + datetime.timedelta(30)):
raise ValidationError('Date cannot be more than 30d future')
if data < (datetime.date.today() - datetime.timedelta(90)):
raise ValidationError('Date cannot be more than 90d past')
return data
class Meta:
model = JournalEntry
fields = ['date','description']
widgets = {'date': DateTypeInput()}
class LineItemForm(ModelForm):
class Meta:
model = LineItem
fields = ['ledger','description','project','cr','dr']
# This init disallows empty formsets
def __init__(self, *arg, **kwarg):
super(LineItemForm, self).__init__(*arg, **kwarg)
self.empty_permitted = False
def clean(self):
cr = self.cleaned_data['cr']
dr = self.cleaned_data['dr']
if cr == None and dr == None:
raise ValidationError('You must enter a CR or DR.')
if cr and dr:
raise ValidationError('You must enter a CR or DR, not both.')
Thanks to #Iain Shelvington again. Edited the following lines to use inline_formset and now works:
LineItemFormSet = inlineformset_factory(JournalEntry, LineItem, fields=('ledger','description','project','cr','dr'), extra=2)
and:
lineitem_formset = LineItemFormSet(request.POST, instance=journal_entry)

Inline formset is not validating when fields are empty

Inline formset is valid when all the fields are empty but when i fill any one field and submit the formset becomes invalid ?
forms.py
class ContactPersonForm(forms.ModelForm):
phone_number = PhoneNumberField(error_messages={'required': 'Please enter your phone number'}, widget=forms.TextInput(attrs={'placeholder': _('Mobile Number')}))
mobile_number = PhoneNumberField(error_messages={'required': 'Please enter your phone number'}, widget=forms.TextInput(attrs={'placeholder': _('Mobile Number')}))
class Meta:
model = ContactPerson
exclude = ('client',)
widgets = {
'first_name': forms.TextInput(attrs={'placeholder': _('First Name')}),
'last_name': forms.TextInput(attrs={'placeholder': _('Last Name')}),
'email': forms.EmailInput(attrs={'placeholder': _('Email')}),
'phone_number': forms.TextInput(attrs={'placeholder': _('Phone Number')}),
'mobile_number': forms.TextInput(attrs={'placeholder': _('Mobile Number')}),
'skype_name': forms.TextInput(attrs={'placeholder': _('Skype Name / Number')}),
'designation': forms.TextInput(attrs={'placeholder': _('Designation')}),
'department': forms.TextInput(attrs={'placeholder': _('Department')}),
}
ContactPersonFormSet = inlineformset_factory(Client, ContactPerson, form=ContactPersonForm, extra=1)
models.py
class ContactPerson(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
salutation = models.CharField(max_length=4, choices=SALUTATIONS)
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
phone_number = models.CharField(max_length=20)
mobile_number = models.CharField(max_length=20)
skype_name = models.CharField(_('Skype Name / Number'), max_length=128)
designation = models.CharField(max_length=128)
department = models.CharField(max_length=128, null=True)
You may add a custom FormSet by inheriting BaseInlineFormSet and make use of the property has_changed()
class ContactPersonFormSet(forms.BaseInlineFormSet):
def clean(self):
if self.has_changed() == False:
raise forms.ValidationError('Please add at least one contact person.')
and then specify it in your fomset_facotry, like
ContactPersonFormSet = inlineformset_factory(Client, ContactPerson, form=ContactPersonForm, formset=ContactPersonFormSet, extra=1)

Django admin admin_order_field with other table

How to sort by custom field in Django admin.
My database's tables are without any ForeignKey,
django framework design by related ship.
This model define:
class UserBaseInfo(BaseModel):
STATUS = [(0, 'not pass'), (1, 'pass')]
SEX = [(0, 'unset'), (1, 'male'), (2, 'female')]
parent_id = models.IntegerField(max_length=11, default=0)
level_id = models.IntegerField(max_length=11, default=1)
phone = models.BigIntegerField(max_length=15, null=True, blank=True, default=None)
nickname = models.CharField(max_length=100)
sex = models.IntegerField(null=False, blank=False, default=1, choices=SEX)
country = models.CharField(max_length=100, null=True, blank=True)
province = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=100, null=True, blank=True)
headimgurl = models.CharField(max_length=255, null=True, blank=True)
status = models.IntegerField(max_length=3, default=0)
updated_time = models.BigIntegerField(max_length=18, null=True, blank=True)
class Meta:
db_table = 'user_base_info'
ordering = ('-created_time', '-updated_time')
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
initial = False
if not self.id:
initial = True
super(UserBaseInfo, self).save(force_insert=force_insert, force_update=force_update, using=using,
update_fields=update_fields)
if initial:
Wallet(user_id=self.id, money=1000).save()
class Wallet(models.Model):
user_id = models.BigIntegerField(max_length=18, primary_key=True, null=False, blank=False, verbose_name=_('UserId'))
money = models.FloatField(null=False, blank=False)
class Meta:
db_table = 'wallet'
This admin
class UserBaseInfoAdmin(CSVAdmin):
list_display = ('nickname', 'avatar', 'level_id', 'parent', 'income', 'sex', 'country', 'province', 'city')
list_filter = ('nickname', 'level_id', 'sex', ('created_time', DateFieldListFilter), ('updated_time', DateFieldListFilter))
search_fields = ('nickname', 'level_id', 'sex', 'created_time', 'updated_time')
list_display_links = ('level_id',)
readonly_fields = ('nickname', 'level_id', 'sex', 'country', 'province', 'city', 'headimgurl',
'language', 'openid', 'privilege', 'created_time', 'updated_time')
list_per_page = 20
list_max_show_all = 20
def avatar(self, data):
return format_html('<img src="%s" height="50px" style="border-radius:50px"/>' % data.headimgurl)
def parent(self, data):
user = UserBaseInfo.objects.filter(pk=data.parent_id).first()
return user.nickname if user else ''
parent.allow_tags = True
parent.admin_order_field = 'parent_id'
def income(self, data):
wallet = Wallet.objects.filter(user_id=data.id).first()
if wallet:
return wallet.money / 100
income.admin_order_field = 'wallet__money'
I want to order by wallet's money, but I don't how to do next;