Reputation: 424
I am trying to make my model so that the URL slug is hyphenated between spaces in the slug field by default. The slug should be limited to only the first six words in TextField
. The TextField()
called questionToProblem
in the same model. Here's what I have:
class Problem(models.Model):
free = models.CharField(max_length = 1, choices = Free)
questionToProblem = models.TextField()
solutionToProblem = models.TextField()
slug = models.CharField(max_length = 250, unique = True)
topic = models.ForeignKey(Topic, on_delete = models.CASCADE)
plainText = models.TextField(default= 'temp')
profile = models.JSONField(default=dict, blank=True) #default is assigned on the recommendation of django docs. DO NOT CHANGE
comments = GenericRelation(Comment)
def save(self, *args, **kwargs):
super().save(*args, **kwargs) #create the problem
cosine = Cosine(2)
self.plainText = LatexNodes2Text().latex_to_text(str(self))
self.profile = cosine.get_profile(self.plainText)
super().save(update_fields=['plainText', 'profile',]) #update the neccessary fields
for query in SavedQuery.objects.all():
query_profile = cosine.get_profile(query.query)
similarity = cosine.similarity_profiles(query_profile, self.profile)
if similarity >= 0.25 and self not in query.results.all():
query.results.add(self)
query.save()
class Meta:
ordering = ('questionToProblem',)
def get_url(self):
return reverse('solution_details', args = [self.topic.slug, self.slug])
def __str__(self):
return self.questionToProblem
My views.py:
def displaySolution(request, topic_slug, problem_slug):
try:
solution = Problem.objects.get(topic__slug = topic_slug, slug = problem_slug)
except Exception as e:
raise e
return render(request, 'solution.html', {'solution' : solution})
Ideally, here's what I want the URL to look like, if the questionToProblem
was "How many bananas do I have in total?"
, and the Topic
key was "modeltopic"
:
http://127.0.0.1:8000/modeltopic/How-many-bananas-do-I-have
Upvotes: 0
Views: 154
Reputation: 1646
Alter your slug field to include blank will help you out with the autosaving bit in the admin. Otherwise the form will complain that it needs a value.
slug = models.CharField(max_length = 250, unique = True, blank=True)
Add a method for the save something like the following. This may not be the best way given you want to use the TextField as the slug source - this may become a performance issue, but if your text is relatively short, and there are few 'new' Problems on a relative basis you may be alright. Use Django's slugify
to deal with alphanumerics, trailing spaces, underscores, hyphens and the like, then split
the text on space hyphen, taking a max of six words (https://docs.python.org/3/library/stdtypes.html#str.split) which then get joined (https://docs.python.org/3/library/stdtypes.html#str.join) back together as a string each separated with a hyphen.
def save(self):
if not self.slug:
# self.slug = slugify(' '.join(self.questionToProblem.split(' ')[:6]))
# or take advantage of split's second argument
# self.slug = slugify(' '.join(self.questionToProblem.split(' ', 5)))
# or to take Selcuk's suggestion:
# coding on the fly here in S/O so no guarantee on this syntax :)
self.slug = '-'.join(slugify(self.questionToProblem).split('-', 5))
return super().save(*args, **kwargs)
Note the use of slugify
which you can import with:
from django.utils.text import slugify
Upvotes: 2