Get username in url [Django] [mongoengine]

混江龙づ霸主 提交于 2020-01-16 19:57:42

问题


I am using django 1.7 with mongoengine. I have created a class Projects :

class Projects(Document):
    user = ReferenceField(User, reverse_delete_rule=CASCADE)
    p_name = StringField(max_length=70, required=True)
    author = StringField(max_length=70, required=True)
    url = StringField(max_length=200, required=True)
    short_discription = StringField(max_length=100, required=True)
    long_discription = StringField()
    logo_url = StringField(max_length=200, required=False)
    logo = ImageField(size=(250, 250, True))
    tags = TaggableManager()

    def __unicode__(self):
        return self.p_name

    def save(self, *args, **kwargs):
        self.p_name = self.p_name
        return super(Projects, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('view_project', args=[self.p_name])

    def get_edit_url(self):
        return reverse('update', args=[self.id])

    def get_delete_url(self):
        return reverse('delete', args=[self.id])

and i am referencing and storing user in my mongodb through my views :

class new_project(CreateView):
    model = Projects
    form_class = NewProjectForm
    success_url = reverse_lazy('registered')
    def get_template_names(self):
        return["new_project.html"]

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.user = self.request.user
        self.object.save()
        return super(new_project, self).form_valid(form)

and mongodb JSON format looks like this :

"user" : ObjectId("54db3e5d7818f4253e5da0db"),

I want to to create user profile where they can see their all projects, for that i created a view :

class UserProjectsListView(ListView):
    model = Projects
    context_object_name = "project"

    def get_template_names(self):
        return ["view_user.html"]

    def get_queryset(self):
        return self.model.objects.filter(user=self.kwargs['pk'])

and my urls.py :

url(r'^new_project/', new_project.as_view(),name='new_project'),
url(r'^project/(?P<pk>[\w\d]+)', view_project.as_view(), name='view_project'),
url(r'^user/(?P<pk>[\w\d]+)/$', UserProjectsListView.as_view(), name='detail'),

The problem with this is that i have to use the object id only in my url, but want to use username instead. Because on the template it renders only username not the object id.

Does anyone know how to use username in urls instead of object id, because rendering object id on template would not be good for security purpose also.

my user creation form :

class UserCreationForm(forms.Form):
    error_messages = {
    'duplicate_username': _("A user with that username already exists."),
    'duplicate_email': _("A user with that email already exists."),
    'password_mismatch': _("The two password fields didn't match."),


    }
    username = forms.RegexField(label=_("Username"), max_length=30,
        regex=r'^[\w.@+-]+$',
        help_text=_("Required. 30 characters or fewer. Letters, digits and "
                      "@/./+/-/_ only."),
        error_messages={
            'invalid': _("This value may contain only letters, numbers and "
                         "@/./+/-/_ characters.")})
    email = forms.EmailField(label=_("Email"), max_length=254,
        help_text=_("Required valid email. 254 characters or fewer."),
        error_messages={
            'invalid': _("This value may contain only valid email address.")})
    password1 = forms.CharField(label=_("Password"),
        widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password confirmation"),
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."))

    def clean_username(self):
        # Since User.username is unique, this check is redundant,
        # but it sets a nicer error message than the ORM. See #13147.
        username = self.cleaned_data["username"]
        try:
            User._default_manager.get(username=username)
        except User.DoesNotExist:
            return username
        raise forms.ValidationError(
            self.error_messages['duplicate_username'],
            code='duplicate_username',
        )
    def clean_email(self):
        # Since User.username is unique, this check is redundant,
        # but it sets a nicer error message than the ORM. See #13147.
        email = self.cleaned_data["email"]
        try:
            User._default_manager.get(email=email)
        except User.DoesNotExist:
            return email
        raise forms.ValidationError(
            self.error_messages['duplicate_email'],
            code='duplicate_email',
        )

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        return password2

    def save(self):
        user = User._default_manager.create_user(
            username=self.cleaned_data['username'],
            email=self.cleaned_data['email'],
            password=self.cleaned_data["password1"])
        return user

I also want to get data from three tables and i have used dev instead of class:

def UserProjectsListView(request,  pk):
    return render_to_response('view_user.html', {
        'tuorial' : Tutorial.objects.filter(user=pk),
        'question' : Question.objects.filter(user=pk),
        'project': Project.objects.filter(user=pk),
        })

P.S. Thanks in advance.


回答1:


If MongoEngine can't simulate joins, it is very simple to do this in two separate queries:

def get_queryset(self):
    user = User.objects.get(username=self.kwargs['username'])
    return self.model.objects(user=user.id)


来源:https://stackoverflow.com/questions/28694144/get-username-in-url-django-mongoengine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!