Generating Django sitemap.xml: How to fix 'get_absolute_url' error - python

I have a “BigPage” model that has an element called “pagename” that has unique set to True. I would like to use the django-sitemaps framework to generate, populate, and continuously update the sitemap.xml file every time a new BigPage model with a new “pagename” element is created by adding the URL myapp.com/pagename to my project’s sitemap.xml file. Here's my BigPage model:
class BigPage(models.Model):
Pagename = models.CharField(max_length=128, blank=True, unique=True, null=True) #they will enter this input into a form field to reserve their unique url at myapp.com/pagename
PageNameOwner = models.CharField(max_length=128, blank=True, null=True) #owner of page enters their name
OwnerGender = models.CharField(max_length=7, choices=(('male', 'Male'), ('female', 'Female')), blank=True, null=True)
PageViewsCounter = models.IntegerField(null=False, default=0)
PageIsRemoved = models.BooleanField(default=False) #true if mods take down a person’s page
def __unicode__(self):
return self.Pagename
I have created the below sitemap.py file and placed it in the folder of my app where the BigPage model resides:
class BigPageSitemap(Sitemap):
changefreq = 'daily'
priority = 0.5
def items(self):
return BigPage.objects.all()
Then, in the main project url.py file (not the app url.py file) I have added this:
sitemaps = {
'Name of Page':BigPageSitemap
}
To the urlpatterns element this:
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
My app url.py has the following url pattern where if a term is entered in the URL field that matches a pagename element that can then be queried to retrieve a BigPage object then it loads that page, but if the entered URL is not equal to a pagename element, it will give the user a 404:
url(r'^(?P<url_param>[a-zA-Z0-9_.-]*)/$', views.view_for_all_BigPages, name='view_for_all_BigPages'),)
After all of this, no sitemap file seems to generate if I check the app folder or main project folder. If I go to myapp.com/sitemap.xml I get the following error:
'BigPage' object has no attribute 'get_absolute_url'
What things have I done wrong? I really appreciate any help. I’ve been trying for days.

from the docs:
There is no location method in this example, but you can provide it in
order to specify the URL for your object. By default, location() calls
get_absolute_url() on each object and returns the result.
you didnot define location() method in your Sitemap class, thats why it is trying to call get_absolute_url() on your model. so you need to define get_absolute_url() in your model like this:
class BigPage(models.Model):
Pagename = models.CharField(max_length=128, blank=True, unique=True, null=True)
# ....
def __unicode__(self):
return self.Pagename
def get_absolute_url(self):
return reverse('view_for_all_BigPages', kwargs={'url_param': self.Pagename})
by the way, model attributes are written in small letters, pagename rather than Pagename.

Related

DJANGO get objects in sql like join

Context: I'm forcing my self to learn django, I already wrote a small php based website, so I'm basically porting over the pages and functions to learn how django works.
I have 2 models
from django.db import models
class Site(models.Model):
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.name
class Combo(models.Model):
username = models.CharField(max_length=50)
password = models.CharField(max_length=50)
dead = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
siteID = models.ForeignKey(Site, on_delete=models.PROTECT)
class Meta:
unique_together = ('username','siteID')
def __str__(self):
return f"{self.username}:{self.password}#{self.siteID.name}"
When creating a view, I want to get the Combo objects, but I want to sort them first by site name, then username.
I tried to create the view, but get errors about what fields I can order by Cannot resolve keyword 'Site' into field. Choices are: dead, id, password, siteID, siteID_id, timestamp, username
def current(request):
current = Combo.objects.filter(dead=False).order_by('Site__name','username')
return render(request, 'passwords/current.html',{'current':current})
Since I'm not necissarily entering the sites into the database in alphabetical order, ordering by siteID wouldn't be useful. Looking for some help to figure out how to return back the list of Combo objects ordered by the Site name object then the username.
You can order this by siteID__name:
def current(request):
current = Combo.objects.filter(dead=False).order_by('siteID__name','username')
return render(request, 'passwords/current.html',{'current':current})
since that is the name of the ForeignKey. But that being said, normally ForeignKeys are not given names that end with an ID, since Django already adds an _id suffix at the end for the database field.
Normally one uses:
class Combo(models.Model):
# …
site = models.ForeignKey(Site, on_delete=models.PROTECT)
if you want to give the database column a different name, you can specify that with the db_column=… parameter [Django-doc]:
class Combo(models.Model):
# …
site = models.ForeignKey(
Site,
on_delete=models.PROTECT,
db_column='siteID'
)

Django admin: How to get path of uploaded file

I have created model field for User Pic and User_pic_url, what i'm trying to do is when i upload image it's path should get populated in user_pic_url.
Note that i'm uploading image from django admin itself. any idea.
snapshot for ref:
Snapshot
Model.py:
class Main(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=100)
about = models.TextField()
contact = models.CharField(default='0', max_length=12)
email = models.CharField(default='-', max_length=50)
linkedin = models.CharField(default='-', max_length=50)
github = models.CharField(default='-', max_length=50)
site_name = models.CharField(default='-', max_length=50)
resume = models.FileField()
cover_letter = models.FileField()
user_pic = models.ImageField()
user_pic_url = models.TextField(default="-")
From Django documentation regarding managing files
Consider the following model, using an ImageField to store a photo:
class Car(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=5, decimal_places=2)
photo = models.ImageField(upload_to='cars')
Any Car instance will have a photo attribute that you can use to get
at the details of the attached photo:
car = Car.objects.get(name="57 Chevy")
car.photo
<ImageFieldFile: cars/chevy.jpg>
car.photo.name
'cars/chevy.jpg'
car.photo.path
'/media/cars/chevy.jpg'
car.photo.url
'http://media.example.com/cars/chevy.jpg'
if you want to get the uploaded path first make sure you have configure you MEDIA_URL MEDIA_ROOT in settings.py and also you have to put your put url patterns for media url given in the documentation
if you have already done that you have to simply put the query set
obj = Main.objects.all().first()
like this when you get any object you have to go to the imagefield and add url after that like this
you have to only put url after all the configuration in the imagefield
print(obj.user_pic.url) <---------you can get your url like this
You don't need a user_pic_url field. You can fetch the data from the user_pic field itself
class Main(models.Model):
# rest of your fields
user_pic = models.ImageField()
#property
def user_pic_url(self):
return self.user_pic.url
Now, you can access the URL directly as,
model_instance = Main.objects.first()
print(model_instance.user_pic_url)

Cant Upload Images to Django Admin

I am working on e-commerce project and i am stuck at this. Whenever admin adds new product,it should also add image related to the product. So i added the the column with ImageField but i am getting error again and again. Here is my code for models
class Product(models.Model):
product_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100, blank=True, null=True)
image = models.ImageField(db_column='image' , blank=True, null=True)
info = models.CharField(max_length=500, blank=True, null=True)
def image_tag(self):
if self.image:
return mark_safe('<img src="%s"/>' % self.image.url)
else:
return 'No Image Found'
image_tag.short_description = 'Image'
and in admin.py
class ProductAdmin(admin.ModelAdmin):
list_display = ('product_id', 'name','image_tag', 'info')
readonly_fields = ('image',)
admin.site.register(Product, ProductAdmin)
But every time i get this error
Exception Type: AttributeError
Exception Value:'bytes' object has no attribute 'url'
I tried using escape but it still not displaying images.I am using MySQL existing database. I could really use the help. Thanks
Currently you are storing image in your database as bytes, which Django does not prefers instead you should first specify MEDIA_ROOT this is folder where your image will be saved and only the URL will be saved in the database. Docs [SOURCE]
I assume you have already setup MEDIA settings and have installed Pillow.
Your ImageField will look like,
# No need to specify db_column as Django already stores by default field's name.
image = models.ImageField(upload_to='users/%Y/%m/%d/', blank=True, null=True)
Now in your templates you can get the image by,
<img src="http://127.0.0.1:8000/media/{{ profile.photo }}" id='profile-photo'>

How implement user matching algorithm into Django app

I'm creating a Django app that allows users to register as either a "mentor" or "mentee". Each user has some information stored in the User that is common across all accounts, while mentors/mentees have a second table (one-to-one) MentorProfile/MenteeProfile with areas of expertise/interest.
The goal is to create a mechanism by which a mentor is assigned to a mentee after running a matching algorithm (such as stable relationship). I have working registration/edit features, however am stuck on how to begin implementing the match.
Is there a way to introduce a button into the Django admin panel that, when clicked:
Pulls the necessary information from the Django app
Makes the Mentor/Mentee matches and assignments
Updates the MentorProfile and MenteeProfile tables with these matches
For what it's worth, we have a working python script that pulls the necessary information from a csv that can make the mentor/mentee relationship assignment. We are simply unsure on how to implement this logic into our app.
EDIT:
Just a general view of my models. Additionally, the User class has the default user attributes (username, firstname, lastname, email, etc.)
Here is my blog/models.py
class User(AbstractUser):
is_mentor = models.BooleanField('Mentor', default=False)
is_mentee = models.BooleanField('Mentee', default=False)
class MenteeProfile(models.Model):
CAREER_CHOICES = [
('Doctor', 'Doctor'),
('Teacher', 'Teacher'),
('Engineer', 'Engineer'),
('Scientist', 'Scientist'),
('Biologist', 'Biologist'),
('Business', 'Business')
]
user=models.OneToOneField(User, on_delete=models.CASCADE)
career_interest1 = models.CharField(max_length=30, default='Doctor', choices=CAREER_CHOICES)
career_interest2 = models.CharField(max_length=30, default='Doctor', choices=CAREER_CHOICES)
career_interest3 = models.CharField(max_length=30, default='Doctor', choices=CAREER_CHOICES)
class MentorProfile(models.Model):
user=models.OneToOneField(User, on_delete=models.CASCADE)
AREA_OF_EXPERTISE = [
('Doctor', 'Doctor'),
('Teacher', 'Teacher'),
('Engineer', 'Engineer'),
('Scientist', 'Scientist'),
('Biologist', 'Biologist'),
('Business', 'Business')
('--', '--') ]
career_expertise1 = models.CharField(max_length=30, default='--', choices=AREA_OF_EXPERTISE)
career_expertise2 = models.CharField(max_length=30, default='--', choices=AREA_OF_EXPERTISE)
career_expertise3 = models.CharField(max_length=30, default='--', choices=AREA_OF_EXPERTISE)
career_expertise4 = models.CharField(max_length=30, default='--', choices=AREA_OF_EXPERTISE)
career_expertise5 = models.CharField(max_length=30, default='--', choices=AREA_OF_EXPERTISE)
career_expertise6 = models.CharField(max_length=30, default='--', choices=AREA_OF_EXPERTISE)
def __str__(self):
return self.user.username
Thanks!
Every Help Will Be Appreciated!
From django docs:
In admin.py file:
class MentorProfileAdmin(admin.ModelAdmin):
#define your list display or fieldsets
....
....
#now need to define urls for custom button in admin template file
def get_urls(self):
"""
generate urls for methods. and attach with admin url
:param self:
"""
urls = super().get_urls()
my_urls = [
url(r'^match-mentee/$', self.match_mentee),
]
return my_urls + urls
def match_mentee(self, request):
"""
here you put the matching logic
"""
....
....
self.message_user(request, "mentor has been assigned to mentee")
return HttpResponseRedirect("../")
For the addition of a custom button in admin template, there are limits so far as I remember when I needed to customise it in django 1.8. So only limited part of admin template can be customised. I would like you to refer the official docs to explore for customisation.
Also, put the url in in button's href to make button working in template.

Django Haystack custom form custom attribute returns no results

I have made my own SearchForm following instructions from Django website, but for some reason if I add my own search field, it doesn't return any results, even when it should return results.
My search_indexes.py:
from haystack import indexes
from my.app.models import MyModel
class MyIndexIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.NgramField(document=True, use_template=True)
my_fieldname = indexes.CharField(model_attr='my_fieldname')
def get_model(self):
return MyModel
My model:
class MyModel(models.Model):
some_field1 = models.CharField(_('Some field 1'), max_length=255)
some_field2 = models.CharField(_('Some field 2'), max_length=255)
my_fieldname = models.CharField(_('My field name'), max_length=255)
My search form:
class MySearchForm(SearchForm):
q = forms.CharField(label="Search", max_length=255, required=False)
my_fieldname = forms.CharField(label="MySearchLabel", max_length=255, required=False)
def search(self):
sqs = super(MySearchForm, self).search()
if self.is_valid() and self.cleaned_data['my_fieldname']:
sqs = sqs.filter(my_fieldname=AutoQuery(self.cleaned_data['my_fieldname']))
return sqs
My urls.py:
urlpatterns += patterns('haystack.views',
url(r'^search/', SearchView(
form_class=MySearchForm
), name='haystack_search'),
)
I have run manage.py rebuild_index, but it doesn't affect. My question is what I am doing wrong here, why I am not getting any results. If I try some queries with q parameters, results are returned normally.
super(MySearchForm, self).search() performs an auto_query() with a default field name of content... As you haven't defined a field like this it will not return any results... Therefore I wouldn't do the super call, but replace with an implementation similar to the original one - but pass a fieldname to auto_query: auto_query(querystring, fieldname='text').
Also make sure to have the template defined correctly if you are searching in it. (If you are chaining multiple filter() calls they will be combined usind and).
Also depending on the search engine you use it will probably offer you a frontend where you can check independently from haystack if the data is indexed properly...

Categories